Redis6.2發佈 地理位置功能增強了什麼?

Redis社區最近剛剛發佈Redis6.2 RC1版本,在本次發佈中,阿里雲Tair團隊(阿里雲內存數據庫產研團隊,負責雲上Redis社區版和Redis企業版Tair)爲社區貢獻了大量高質量代碼與功能,其中關於地理位置查詢能力的提升上,阿里雲貢獻了GEOSEARCH和GEOSEARCHSTORE兩個重要而強大的API。本文通過分析這兩個全新的API,對Redis在地理位置型應用進行深入剖析,並延伸介紹了阿里雲Tair在地理位置上的更多強大功能與應用場景。

1.Redis 6.2 GEOSEARCH命令詳解

Redis自3.2版本,增加了地理位置的相關API:

  • GEOADD 將給定的空間元素(緯度、經度、名字)添加到指定的鍵裏面。

  • GEOPOS 從鍵裏面返回所有給定位置元素的位置(經度和緯度)。

  • GEODIST 返回兩個給定位置之間的距離。

  • GEORADIUS 以給定的經緯度爲中心, 返回與中心的距離不超過給定最大距離的所有位置元素。

  • GEORADIUSBYMEMBER 跟GEORADIUS類似,指定GEO集合中某個成員爲中心。

  • GEOHASH 返回一個或多個位置元素的 Geohash 表示。

然而隨着互聯網生活的本地化進程加快,諸如同城購,社區團購與買菜、電子單車圍欄等基於地理位置的業務的飛速發展,過去開源Redis只能搜索圓形區域的能力並不能滿足用戶的搜索需求,在最新版Redis 6.2中,阿里雲Tair團隊將阿里雲Redis企業版Tair性能增強型中包含的相關矩形搜索能力貢獻給了社區。

新增的GEOSEARCH和GEOSEARCHSTORE命令擁有更豐富的語法,滿足了搜索矩形的應用需求。

GEOSEARCH key 
[FROMMEMBER member] [FROMLONLAT long lat] 
[BYRADIUS radius unit] [BYBOX width height unit] 
[WITHCOORD] [WITHDIST] [WITHHASH] 
[COUNT count] [ASC|DESC]

該API返回使用GEOADD填充的地理空間信息有序集合中位於給定形狀所劃定的區域邊界內的所有成員。

其中搜索中心有兩種指定方式:

  • FROMMEMBER:從已經存在的key中讀取經緯度。

  • FROMLONLAT:從用戶參數傳遞經緯度。

搜索條件按照下面兩種:

  • BYRADIUS:根據給定半徑長度按照圓形搜索,命令效果等同於GEORADIUS。

  • BYBOX:根據給定的width和height按照矩形搜索,矩形是軸對稱矩形。

後面更多的可選參數如下:

  • WITHCOORD:返回匹配的經緯度座標。

  • WITHDIST:返回距離,距離單位按照radius或者height/width單位轉換。

  • WITHHASH:返回GeoHash計算的值。

  • COUNT count:只返回count個元素。注意,這裏的count是全部搜索完成之後才過濾的,也就是不能減少搜索的CPU消耗,但是返回元素少,可以相應降低網絡帶寬的利用率。

  • ASC|DESC:對滿足條件的點按照距離排序。

GEOSEARCHSTORE與GEOSEARCH相似,只是將搜索結果存儲在指定的key中。

舉例如下,對於一個正方形(橙色區域)以及其內接圓(藍色區域)的搜索,可以看到,位於正方形,但是沒有在內接圓中的點edge1和edge2可以通過BYBOX指定矩形搜索的方式被搜索出來:

127.0.0.1:6379> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
127.0.0.1:6379> GEOADD Sicily 12.758489 38.788135 "edge1" 17.241510 38.788135 "edge2"
(integer) 2
127.0.0.1:6379> GEOSEARCH Sicily FROMLONLAT 15 37 BYRADIUS 200 km ASC
1) "Catania"
2) "Palermo"
127.0.0.1:6379> GEOSEARCH Sicily FROMLONLAT 15 37 BYBOX 400 400 km ASC
1) "Catania"
2) "Palermo"
3) "edge2"
4) "edge1"

注:左右滑動閱覽

2.Redis GEO的不足

從實現原理上講,Redis本身的GEO功能底層是根據GeoHash算法,將地理位置座標轉換爲52bit的整形數字之後,存儲在Sorted Set中。因爲GeoHash的特性,地理位置距離越近則數值大小越相似,然後通過ZRANGEBYSCORE key min max WITHSCORES查詢Sorted Set範圍內的點並判斷距離是否在搜索範圍內。

目前在最新版6.2 RC1中雖然支持了圓形與矩形的搜索,但是Redis GEO仍舊有很多場景限制,例如:

  • 搜索地域如果是不規則多邊形怎麼辦?

  • 如果想搜索線與面(例如外賣員的軌跡與地域關係)、面與面的關係怎麼辦?

要解決這些問題,需要從GIS原理重新審視。Redis目前使用的GeoHash原理本質上是對二維座標進行了降維,將其表示爲一個long數字或者base32編碼,但是這種索引只適合查詢點和點的關係,對於更復雜的線與面的關係,需要更復雜的索引結構RTree1來解決。RTree可以將多個不規則多邊形求Minimum bounding box(最小限定矩形)之後存儲在一棵RTree中用來檢索。

正是由於複雜的運算和存儲索引,傳統關係型如PostGIS和落盤型(On-Disk Database)數據庫在地理位置高併發更新和查詢時效率不高。而將數據結構化在內存數據庫中(In-Memory Database),結合Tair增強性能的高吞吐引擎可以使得存儲查詢效率得到能力的量級提升。

3.阿里雲TairGIS介紹

TariGIS是阿里雲Redis企業版性能增強型其中的一個Module,使用RTree做索引,支持GIS(Geographic Information System,地理信息系統)各種豐富的API查詢2。TairGIS不僅兼容Redis GEO,並且支持線、面的查詢,功能更加強大,能夠更廣泛地用於各類基於地理位置的應用及業務中。

主要的功能如下:

  • 使用RTree索引

  • 支持點、線、面的相關查詢(包含,相交,臨近)

  • 兼容Redis GEO

如下展示TairGIS兼容上面Redis GEO例子並增加線和麪的搜索:

// 使用TairGIS可以添加 POINT(點)/LINESTRING(線)/POLYGON(面) 三種圖形
127.0.0.1:7379> GIS.ADD Sicily Palermo 'POINT (13.361389 38.115556)' Catania 'POINT (15.087269 37.502669)'  // 添加點
(integer) 2
127.0.0.1:7379> GIS.ADD Sicily edge1 'POINT (12.758489 38.788135)' edge2 'POINT (17.241510 38.788135)'
(integer) 2
127.0.0.1:7379> GIS.SEARCH Sicily RADIUS 15 37 200 km // 使用半徑查詢
1) (integer) 2
2) 1) "Palermo"
   2) "POINT(13.361389 38.115556)"
   3) "Catania"
   4) "POINT(15.087269 37.502669)"
127.0.0.1:7379> GIS.ADD Sicily polygon 'POLYGON ((13.361389 38.115556, 15.087269 37.502669, 17.241510 38.788135))' // 添加 Palermo,Catania,edge2的三角形
(integer) 1
127.0.0.1:7379> GIS.SEARCH Sicily GEOM "POLYGON ((12.7484 35.2018, 12.7484 38.7981, 17.2515 38.7981, 17.2515 35.2018))"  // 等同於 BYBOX 400 400 km,TairGIS可以指定任意形狀的多邊形查詢,而非受限於矩形
1) (integer) 5
2) 1) "Palermo"
   2) "POINT(13.361389 38.115556)"
   3) "Catania"
   4) "POINT(15.087269 37.502669)"
   5) "edge1"
   6) "POINT(12.758489 38.788135)"
   7) "edge2"
   8) "POINT(17.24151 38.788135)"
   9) "polygon"
   10) "POLYGON((13.361389 38.115556,15.087269 37.502669,17.24151 38.788135))"
127.0.0.1:7379> GIS.SEARCH Sicily GEOM "POLYGON ((12.7484 35.2018, 12.7484 38.7981, 17.2515 38.7981))"  // 使用三角形查詢,可以看到edge2被排除,因爲polygon和三角形有重合,所以被查詢出來
1) (integer) 4
2) 1) "Palermo"
   2) "POINT(13.361389 38.115556)"
   3) "Catania"
   4) "POINT(15.087269 37.502669)"
   5) "edge1"
   6) "POINT(12.758489 38.788135)"
   7) "polygon"
   8) "POLYGON((13.361389 38.115556,15.087269 37.502669,17.24151 38.788135))"
127.0.0.1:7379>

注:左右滑動閱覽

TairGIS的API如下所示:

  • GIS.ADD 將點/線/面添加到key中(每key是一個RTree索引區域)。

  • GIS.GET 獲取添加的點/線/面。

  • GIS.DEL 刪除添加的某個點/線/面。

  • GIS.WITHIN 給定一個範圍,可以是不規則圖形,搜索此範圍內的點/線/面。

  • GIS.CONTAINS 給定一個範圍,判斷包含此範圍的點/線/面的集合。

  • GIS.INTERSECTS 給定一個範圍,判斷哪些點/線/面和此範圍相交的集合。

  • GIS.SEARCH 可以指定圓心和半徑搜索,類Redis語法的Near語義。

  • GIS.GETALL 獲取一個key下所有的點/線/面,通過選項控制返回格式。

通過使用TairGIS可以構建各種豐富的基於地理位置的應用,舉例如下:

本地生活

在淘寶的門店服務中,使用TairGIS做商家服務範圍(一個面)與消費者(一個點)之間的關係判斷,從而確定消費者是否在商家的服務範圍中。

電子圍欄

判斷共享單車是否在禁停區內,是否已經歸還到還車區(通過點和麪的包含關係來判斷),電子圍欄用途非常廣泛,還包括安全應用如兒童電子圍欄,也包括無人機起飛禁飛區判定等。

疫情防控

在疫情期間,判斷用戶的軌跡(一條線)是否經過疫區(一個面),即判斷線與面的相交關係即可確認用戶是否經過疫區。具體方案可參考:使用TairGIS實現用戶軌跡監測

https://help.aliyun.com/document_detail/163537.html

圖7. 構建用戶軌跡判定應用

目前包含上述TairGIS強大地理位置能力的阿里雲Redis企業版性能增強型限時限量特惠,新購和續費年付5折,月付7折,Redis全兼容,更強大性能,更大帶寬,更大連接數,更豐富實用的數據結構,具備全球分佈式多活、數據閃回等多個企業級能力。

參考文獻:

1.RTree工作原理介紹:

Guttman, A. (1984). "R-Trees: A Dynamic Index Structure for Spatial Searching"

2.TairGIS命令文檔:

https://help.aliyun.com/document_detail/145971.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章