Redis中的GEO地理位置模块怎么用
这篇文章主要介绍了Redis中的GEO地理位置模块怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
GEO是 Redis 在3.2版本之后新增的地理位置模块,意味可以用 Redis 来实现附近的地点功能。【相关推荐:Redis视频教程】
用数据库计算一般的方法都是通过矩形区域来限定元素的数量,然后对区域内的元素进行全量距离计算再排序。这样可以明显减少计算量。
selectidfrompositionswherex0-r<x<x0+randy0-r<y<y0+r
以上SQL为了增加性能,需要在经纬度坐标加上双向复合索引。但是数据库查询性能毕竟有限,如果在高并发场合,这可能并不是一个很好的方案。
GEO算法业界比较通用的地理位置距离排序算法是 GeoHash
算法,Redis 也使用 GeoHash
算法。
GeoHash
算法将 二维的经纬度数据映射到一维的整数,这样所有的元素都将在挂载到一条线上,距离靠近的二维坐标映射到一维后的点之间距离也会很接近。当我们想要计算「附近的人时」,首先将目标位置映射到这条线上,然后在这个一维的线上获取附近的点就行了。
算法实现,它将整个地球看成一个 二维平面,然后划分成了一系列正方形的方格,就好比围棋棋盘。所有的地图元素坐标都将放置于唯一的方格中。方格越小,坐标越精确。然后对这些方格进行整数编码,越是靠近的方格编码越是接近。
编码之后,每个地图元素的坐标都将变成一个整数,通过这个整数可以还原出元素的坐标,整数越长,还原出来的坐标值的损失程度就越小。
GeoHash
算法会继续对这个整数做一次 base32
编码 (0-9,a-z 去掉 a,i,l,o 四个字母)
变成一个字符串。
在 Redis 里面,经纬度使用 52 位的整数进行编码,放进了 zset
里面,zset
的 value
是元素的 key
,score
是 GeoHash
的 52 位整数值。
在使用 Redis 进行 Geo 查询时,我们要时刻想到它的内部结构实际上只是一个 zset(skiplist)
。通过 zset
的 score
排序就可以得到坐标附近的其它元素 (实际情况要复杂一些,不过这样理解足够了),通过将 score
还原成坐标值就可以得到元素的原始坐标。
1. 增加 geoadd
geoaddkeylongitudelatitudemember[longitudelatitudemember...]
127.0.0.1:6379>geoaddbeijing116.40385639.924043gugong(integer)1127.0.0.1:6379>geoaddbeijing116.34362039.947633dongwuyuan(integer)1127.0.0.1:6379>geoaddbeijing116.32864339.900272xizhan116.41532439.931231meishuguan116.41685239.887607tiantan(integer)3
删除用 zset 的 zrem
即可
2. 距离 geodist
geodistkeymember1member2[unit]
127.0.0.1:6379>geodistbeijinggugongxizhankm"6.9402"127.0.0.1:6379>geodistbeijinggugongdongwuyuan#默认单位m"5768.5737"127.0.0.1:6379>geodistbeijingxizhanxizhan"0.0000"
距离单位可以是 m、km、ml、ft,分别代表米、千米、英里和尺。
3. 位置 geopos
geoposkeymember[member...]
127.0.0.1:6379>geoposbeijinggugong1)1)"116.4038559794426"2)"39.92404192186725"127.0.0.1:6379>geoposbeijingtiantanxizhan1)1)"116.41685396432877"2)"39.887607839922914"2)1)"116.32864147424698"2)"39.900271306834973"
4. hash值 geohash
geohashkeymember[member...]
127.0.0.1:6379>geohashbeijinggugong1)"wx4g0gfwqk0"
经纬度字符串编码是 base32
编码,可以通过 http://geohash.org/wx4g0gfwqk0
直接查找经纬度
5. 附近地点 georadiusbymember
1、查询 ireader
范围 20
公里以内最多 3
个元素按距离正排,它不会排除自身(倒排使用用 desc
)
127.0.0.1:6379>georadiusbymembercompanyireader20kmcount3asc1)"ireader"2)"juejin"3)"meituan"
2、三个可选参数 withcoord withdist withhash
用来携带附加参数, withdist
很有用,它可以用来显示距离
georadiusbymemberkeymemberradiusm|km|ft|mi[WITHCOORD][WITHDIST][WITHHASH][COUNTcount][ASC|DES]
127.0.0.1:6379>georadiusbymemberbeijinggugong5kmwithcoordwithdistwithhashcount3asc1)1)"gugong"2)"0.0000"3)(integer)40698855689324434)1)"116.4038559794426"2)"39.92404192186725"2)1)"meishuguan"2)"1.2634"3)(integer)40698857103904354)1)"116.41532510519028"2)"39.93123039107514"3)1)"tiantan"2)"4.2014"3)(integer)40698853985025574)1)"116.41685396432877"2)"39.887607839922914"
3、根据坐标值来查询附近的元素
georadiuskeylongitudelatituderadiusm|km|ft|mi[WITHCOORD][WITHDIST][WITHHASH][COUNTcount][ASC|DES]
127.0.0.1:6379>georadiusbeijing116.38388239.9220615kmwithcoordwithdistwithhashcount3asc1)1)"gugong"2)"1.7180"3)(integer)40698855689324434)1)"116.4038559794426"2)"39.92404192186725"2)1)"meishuguan"2)"2.8693"3)(integer)40698857103904354)1)"116.41532510519028"2)"39.93123039107514"3)1)"dongwuyuan"2)"4.4588"3)(integer)40698798364196884)1)"116.34361892938614"2)"39.94763257169722"注意事项
实际应用中数据可能会有百万千万条,我们知道 Redis Geo
将全部放在一个 zset
集合中。在 Redis 的集群环境中,集合可能会从一个节点迁移到另一个节点,如果单个 key
的数据过大,会对集群的迁移工作造成较大的影响,在集群环境中单个 key
对应的数据量不宜超过 1M
,否则会导致集群迁移出现卡顿现象,影响线上服务的正常运行。
所以,这里建议 Geo
的数据使用单独的 Redis 实例部署,不使用集群环境。
如果数据量过亿甚至更大,就需要对 Geo
数据进行拆分,按国家拆分、按省拆分,按市拆分,在人口特大城市甚至可以按区拆分。这样就可以显著降低单个 zset
集合的大小。
感谢你能够认真阅读完这篇文章,希望小编分享的“Redis中的GEO地理位置模块怎么用”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。