婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Redis 的 GeoHash詳解

Redis 的 GeoHash詳解

熱門標簽:b2b外呼系統 臺灣電銷 高碑店市地圖標注app 四川穩定外呼系統軟件 一個地圖標注多少錢 南京手機外呼系統廠家 400電話辦理的口碑 地圖標注工廠入駐 廊坊外呼系統在哪買

Redis 在 3.2 版本以后增加了地理位置 GEO 模塊,意味著我們可以使用 Redis 來實現摩拜單車「附近的 Mobike」、美團和餓了么「附近的餐館」這樣的功能了。

用數據庫來算附近的人

地圖元素的位置數據使用二維的經緯度表示,經度范圍 (-180, 180],緯度范圍 (-90, 90],緯度正負以赤道為界,北正南負,經度正負以本初子午線 (英國格林尼治天文臺) 為界,東正西負。比如掘金辦公室在望京 SOHO,它的經緯度坐標是 (116.48105,39.996794),都是正數,因為中國位于東北半球。

當兩個元素的距離不是很遠時,可以直接使用勾股定理就能算得元素之間的距離。我們平時使用的「附近的人」的功能,元素距離都不是很大,勾股定理算距離足矣。不過需要注意的是,經緯度坐標的密度不一樣 (經度總共 360 度,緯度總共 180 度),勾股定律計算平方差時之后再求和時,需要按一定的系數比加權求和。

現在,如果要計算「附近的人」,也就是給定一個元素的坐標,然后計算這個坐標附近的其它元素,按照距離進行排序,該如何下手?

如果現在元素的經緯度坐標使用關系數據庫 (元素 id, 經度 x, 緯度 y) 存儲,你該如何計算?

首先,你不可能通過遍歷來計算所有的元素和目標元素的距離然后再進行排序,這個計算量太大了,性能指標肯定無法滿足。一般的方法都是通過矩形區域來限定元素的數量,然后對區域內的元素進行全量距離計算再排序。這樣可以明顯減少計算量。如何劃分矩形區域呢?可以指定一個半徑 r,使用一條 SQL 就可以圈出來。當用戶對篩出來的結果不滿意,那就擴大半徑繼續篩選。

select id from positions where x0-r  x  x0+r and y0-r  y  y0+r

為了滿足高性能的矩形區域算法,數據表需要在經緯度坐標加上雙向復合索引 (x, y),這樣可以最大優化查詢性能。

但是數據庫查詢性能畢竟有限,如果「附近的人」查詢請求非常多,在高并發場合,這可能并不是一個很好的方案。

GeoHash 算法

業界比較通用的地理位置距離排序算法是 GeoHash 算法,Redis 也使用 GeoHash 算法。GeoHash 算法將二維的經緯度數據映射到一維的整數,這樣所有的元素都將在掛載到一條線上,距離靠近的二維坐標映射到一維后的點之間距離也會很接近。當我們想要計算「附近的人時」,首先將目標位置映射到這條線上,然后在這個一維的線上獲取附近的點就行了。

那這個映射算法具體是怎樣的呢?它將整個地球看成一個二維平面,然后劃分成了一系列正方形的方格,就好比圍棋棋盤。所有的地圖元素坐標都將放置于唯一的方格中。方格越小,坐標越精確。然后對這些方格進行整數編碼,越是靠近的方格編碼越是接近。那如何編碼呢?一個最簡單的方案就是切蛋糕法。設想一個正方形的蛋糕擺在你面前,二刀下去均分分成四塊小正方形,這四個小正方形可以分別標記為 00,01,10,11 四個二進制整數。然后對每一個小正方形繼續用二刀法切割一下,這時每個小小正方形就可以使用 4bit 的二進制整數予以表示。然后繼續切下去,正方形就會越來越小,二進制整數也會越來越長,精確度就會越來越高。

上面的例子中使用的是二刀法,真實算法中還會有很多其它刀法,最終編碼出來的整數數字也都不一樣。

編碼之后,每個地圖元素的坐標都將變成一個整數,通過這個整數可以還原出元素的坐標,整數越長,還原出來的坐標值的損失程度就越小。對于「附近的人」這個功能而言,損失的一點精確度可以忽略不計。

GeoHash 算法會繼續對這個整數做一次 base32 編碼 (0-9,a-z 去掉 a,i,l,o 四個字母) 變成一個字符串。在 Redis 里面,經緯度使用 52 位的整數進行編碼,放進了 zset 里面,zset 的 value 是元素的 key,score 是 GeoHash 的 52 位整數值。zset 的 score 雖然是浮點數,但是對于 52 位的整數值,它可以無損存儲。

在使用 Redis 進行 Geo 查詢時,我們要時刻想到它的內部結構實際上只是一個zset(skiplist)。通過 zset 的 score 排序就可以得到坐標附近的其它元素 (實際情況要復雜一些,不過這樣理解足夠了),通過將 score 還原成坐標值就可以得到元素的原始坐標。

Redis 的 Geo 指令基本使用

Redis 提供的 Geo 指令只有 6 個,讀者們瞬間就可以掌握。使用時,讀者務必再次想起,它只是一個普通的 zset 結構。

增加

geoadd 指令攜帶集合名稱以及多個經緯度名稱三元組,注意這里可以加入多個三元組

127.0.0.1:6379> geoadd company 116.48105 39.996794 juejin
(integer) 1
127.0.0.1:6379> geoadd company 116.514203 39.905409 ireader
(integer) 1
127.0.0.1:6379> geoadd company 116.489033 40.007669 meituan
(integer) 1
127.0.0.1:6379> geoadd company 116.562108 39.787602 jd 116.334255 40.027400 xiaomi
(integer) 2

距離

geodist 指令可以用來計算兩個元素之間的距離,攜帶集合名稱、2 個名稱和距離單位。

127.0.0.1:6379> geodist company juejin ireader km
"10.5501"
127.0.0.1:6379> geodist company juejin meituan km
"1.3878"
127.0.0.1:6379> geodist company juejin jd km
"24.2739"
127.0.0.1:6379> geodist company juejin xiaomi km
"12.9606"
127.0.0.1:6379> geodist company juejin juejin km
"0.0000"

我們可以看到掘金離美團最近,因為它們都在望京。距離單位可以是 m、km、ml、ft,分別代表米、千米、英里和尺。

獲取元素位置

geopos 指令可以獲取集合中任意元素的經緯度坐標,可以一次獲取多個。

127.0.0.1:6379> geopos company juejin
1) 1) "116.48104995489120483"
 2) "39.99679348858259686"
127.0.0.1:6379> geopos company ireader
1) 1) "116.5142020583152771"
 2) "39.90540918662494363"
127.0.0.1:6379> geopos company juejin ireader
1) 1) "116.48104995489120483"
 2) "39.99679348858259686"
2) 1) "116.5142020583152771"
 2) "39.90540918662494363"

我們觀察到獲取的經緯度坐標和 geoadd 進去的坐標有輕微的誤差,原因是 geohash 對二維坐標進行的一維映射是有損的,通過映射再還原回來的值會出現較小的差別。對于「附近的人」這種功能來說,這點誤差根本不是事。

獲取元素的 hash 值

geohash 可以獲取元素的經緯度編碼字符串,上面已經提到,它是 base32 編碼。 你可以使用這個編碼值去 http://geohash.org/${hash}中進行直接定位,它是 geohash 的標準編碼值。

127.0.0.1:6379> geohash company ireader
1) "wx4g52e1ce0"
127.0.0.1:6379> geohash company juejin
1) "wx4gd94yjn0"

讓我們打開地址 http://geohash.org/wx4g52e1ce0,觀察地圖指向的位置是否正確。

很好,就是這個位置,非常準確。

附近的公司

georadiusbymember 指令是最為關鍵的指令,它可以用來查詢指定元素附近的其它元
素,它的參數非常復雜。

# 范圍 20 公里以內最多 3 個元素按距離正排,它不會排除自身
127.0.0.1:6379> georadiusbymember company ireader 20 km count 3 asc
1) "ireader"
2) "juejin"
3) "meituan"
# 范圍 20 公里以內最多 3 個元素按距離倒排
127.0.0.1:6379> georadiusbymember company ireader 20 km count 3 desc
1) "jd"
2) "meituan"
3) "juejin"
# 三個可選參數 withcoord withdist withhash 用來攜帶附加參數
# withdist 很有用,它可以用來顯示距離
127.0.0.1:6379> georadiusbymember company ireader 20 km withcoord withdist withhash count 3 asc
1) 1) "ireader"
 2) "0.0000"
 3) (integer) 4069886008361398
 4) 1) "116.5142020583152771"
 2) "39.90540918662494363"
2) 1) "juejin"
 2) "10.5501"
 3) (integer) 4069887154388167
 4) 1) "116.48104995489120483"
 2) "39.99679348858259686"
3) 1) "meituan"
 2) "11.5748"
 3) (integer) 4069887179083478
 4) 1) "116.48903220891952515"
 2) "40.00766997707732031"

除了 georadiusbymember 指令根據元素查詢附近的元素,Redis 還提供了根據坐標值來查詢附近的元素,這個指令更加有用,它可以根據用戶的定位來計算「附近的車」,「附近的餐館」等。它的參數和 georadiusbymember 基本一致,除了將目標元素改成經緯度坐標值。

127.0.0.1:6379> georadius company 116.514202 39.905409 20 km withdist count 3 asc
1) 1) "ireader"
 2) "0.0000"
2) 1) "juejin"
 2) "10.5501"
3) 1) "meituan"
 2) "11.5748"

小結 注意事項

在一個地圖應用中,車的數據、餐館的數據、人的數據可能會有百萬千萬條,如果使用Redis 的 Geo 數據結構,它們將全部放在一個 zset 集合中。在 Redis 的集群環境中,集合可能會從一個節點遷移到另一個節點,如果單個 key 的數據過大,會對集群的遷移工作造成較大的影響,在集群環境中單個 key 對應的數據量不宜超過 1M,否則會導致集群遷移出現卡頓現象,影響線上服務的正常運行。

所以,這里建議 Geo 的數據使用單獨的 Redis 實例部署,不使用集群環境。

如果數據量過億甚至更大,就需要對 Geo 數據進行拆分,按國家拆分、按省拆分,按市拆分,在人口特大城市甚至可以按區拆分。這樣就可以顯著降低單個 zset 集合的大小。

到此這篇關于Redis 的 GeoHash詳解的文章就介紹到這了,更多相關Redis 的 GeoHash內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • 詳解PHP使用Redis存儲session時的一個Warning定位

標簽:定州 河源 泰州 南寧 畢節 甘南 拉薩 伊春

巨人網絡通訊聲明:本文標題《Redis 的 GeoHash詳解》,本文關鍵詞  Redis,的,GeoHash,詳解,Redis,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Redis 的 GeoHash詳解》相關的同類信息!
  • 本頁收集關于Redis 的 GeoHash詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    日本道在线观看一区二区| 亚洲五月六月丁香激情| 成人激情视频网站| 成人精品免费看| av成人老司机| 在线免费观看日本一区| 精品少妇一区二区三区日产乱码 | 欧美剧情电影在线观看完整版免费励志电影 | 一区二区高清视频在线观看| 黄网站免费久久| **欧美大码日韩| 国产在线观看一区二区| 欧美电影免费观看高清完整版在线 | 亚洲与欧洲av电影| 91亚洲永久精品| 亚洲国产精品人人做人人爽| 色综合婷婷久久| 国产精品久久久久久久午夜片| 97久久超碰国产精品电影| av在线不卡网| 亚洲色欲色欲www| 欧美日韩国产免费一区二区 | 亚洲欧洲日韩在线| 欧美最猛黑人xxxxx猛交| 免费观看久久久4p| 国产精品中文字幕日韩精品| 亚洲自拍偷拍欧美| 日韩精品专区在线影院观看| 精彩视频一区二区三区| 国产精品免费观看视频| 另类小说欧美激情| 在线不卡a资源高清| 亚洲成人1区2区| 欧美乱妇20p| 国内一区二区在线| 中文字幕乱码久久午夜不卡| 国产成人av电影在线观看| 国产精品天干天干在线综合| 色综合婷婷久久| 亚洲精品国产精品乱码不99| 91理论电影在线观看| 日本亚洲一区二区| 亚洲精品国产第一综合99久久| 91在线高清观看| 成人黄页在线观看| 日本sm残虐另类| 国产精品成人在线观看| 日韩女优av电影在线观看| 国产在线视频一区二区三区| 亚洲精品欧美二区三区中文字幕| 精品福利一二区| 精品国产乱码久久| 精品国产免费一区二区三区香蕉| 欧美xxxxxxxx| 精品91自产拍在线观看一区| 精品剧情v国产在线观看在线| 欧美综合欧美视频| 欧美日本不卡视频| 久久综合久久综合亚洲| 日韩精品中文字幕一区| 日本人妖一区二区| 中文字幕亚洲一区二区av在线| 亚洲国产精品影院| 91免费国产在线| 国产精品无码永久免费888| 国产精品久久久久久久久晋中 | 亚洲午夜三级在线| 亚洲大尺度视频在线观看| 日韩av不卡一区二区| 国产成人8x视频一区二区| 91麻豆精品在线观看| 欧美日韩精品一区二区三区| 欧洲av在线精品| 制服.丝袜.亚洲.中文.综合| 国产激情精品久久久第一区二区 | 日韩一区二区免费在线观看| 欧美色国产精品| 国产欧美综合在线观看第十页| 久久婷婷久久一区二区三区| 中文天堂在线一区| 亚洲综合在线第一页| 极品尤物av久久免费看| 色婷婷av一区二区三区gif| 精品电影一区二区| 337p粉嫩大胆色噜噜噜噜亚洲| 亚洲天堂精品视频| 精品亚洲porn| 欧美成人aa大片| 日韩一区在线看| 国产成人在线视频免费播放| 欧美变态凌虐bdsm| 久久国产麻豆精品| 欧美日韩国产123区| 国产精品久久一卡二卡| 亚洲国产精品久久人人爱| 国模无码大尺度一区二区三区| 色综合色狠狠综合色| 国产精品久久久久久久蜜臀| 国产成人精品一区二| 91精品国产一区二区三区| 欧美成人欧美edvon| 日本美女视频一区二区| 欧美精三区欧美精三区| 婷婷成人综合网| 一本大道av一区二区在线播放| 欧美日韩黄色一区二区| 亚洲国产视频a| 久久国产精品99精品国产| 欧美日韩国产精品自在自线| 亚洲三级小视频| 欧美日韩在线播放三区四区| 亚洲人被黑人高潮完整版| 欧美女孩性生活视频| 国精产品一区一区三区mba视频| 国产欧美日韩精品a在线观看| 欧美影视一区在线| 成人黄色网址在线观看| 国产一区二区免费在线| 午夜日韩在线电影| 亚洲综合一二区| 综合久久给合久久狠狠狠97色| 精品国产区一区| 日韩久久免费av| 欧美二区三区91| 欧美日韩国产精品自在自线| 色婷婷精品大在线视频| hitomi一区二区三区精品| 91色.com| 在线观看免费视频综合| 欧美日韩成人综合在线一区二区| 色综合天天性综合| 欧美色倩网站大全免费| 69av一区二区三区| 日韩一区二区三区三四区视频在线观看 | 风间由美一区二区三区在线观看 | 亚洲欧美激情视频在线观看一区二区三区| 91麻豆蜜桃一区二区三区| 大白屁股一区二区视频| www.欧美色图| 91免费观看在线| 7777女厕盗摄久久久| 欧美一区二区网站| 中文字幕一区二区三区av| 久久综合久色欧美综合狠狠| 久久久亚洲精品一区二区三区| 国产人成一区二区三区影院| 亚洲欧美经典视频| 亚洲午夜成aⅴ人片| 久久爱www久久做| 色狠狠一区二区三区香蕉| 日韩精品在线看片z| 亚洲一区二区三区中文字幕在线| 美腿丝袜亚洲三区| 91丨porny丨户外露出| 日韩欧美一级在线播放| 亚洲一二三专区| 色综合天天综合在线视频| 国产欧美日韩久久| 极品销魂美女一区二区三区| 欧美在线一二三四区| 日韩伦理免费电影| 成人免费毛片app| 欧美成人女星排名| 日韩1区2区日韩1区2区| 欧美三级欧美一级| 国产精品免费视频一区| 91女人视频在线观看| 国产精品成人免费在线| aaa亚洲精品| 国产欧美日韩三区| 成人av电影观看| 一区二区三区免费在线观看| av电影天堂一区二区在线观看| 国产精品视频一二| 色综合久久综合| 亚洲女同ⅹxx女同tv| 色综合久久九月婷婷色综合| 美女免费视频一区| 久久精品视频在线免费观看| 极品少妇一区二区三区精品视频| 日韩欧美中文字幕一区| 国产一区二区在线影院| 国产精品欧美一区喷水| 97久久精品人人爽人人爽蜜臀| 一区二区三区蜜桃| 日韩你懂的在线观看| 成人一级片在线观看| 亚洲天堂精品视频| 日韩视频一区二区三区在线播放| 国产高清无密码一区二区三区| 亚洲色图在线视频| 555夜色666亚洲国产免| 成人爱爱电影网址| 日韩国产在线观看| 国产欧美精品国产国产专区| 欧美日韩成人综合天天影院 | 亚洲黄色av一区| 精品国产1区2区3区| 欧美精三区欧美精三区| 国产精品一二二区|