笔者之前文章介绍过geohash算法,那么今天,我们来讲一下redis的geo功能 。
文章插图
GeoHash与Z阶曲线的关系
1 引言“附近的人”在社交类App已成为标配的功能,简单一点的实现方式可以把坐标存至关系型数据库,通过计算的坐标点距离实现,这种计算可行但计算速度远不及内存操作级别的NoSql数据库 。基于Redis的geo就可以轻松实现 。
2 Redis处理位置坐标点的思路Redis中经纬度使用52位的整数进行编码,放进zset中,zset的value元素是key,score是GeoHash的52位整数值 。在使用Redis进行Geo查询时,其内部对应的操作其实只是zset(skiplist)的操作 。通过zset的score进行排序就可以得到坐标附近的其它元素,通过将score还原成坐标值就可以得到元素的原始坐标 。
Redis中处理这些地理位置坐标点的思想是: 二维平面坐标点 --> 一维整数编码值 --> zset(score为编码值) --> zrangebyrank(获取score相近的元素)、zrangebyscore --> 通过score(整数编码值)反解坐标点 --> 附近点的地理位置坐标 。
3 redis GEO的使用Geo指令,底层是普通的zset结构,提供6个命令 。
3.1 geoadd
文章插图
3.2 geodist
文章插图
3.3 geopos
文章插图
GeoHash对二维经纬度坐标进行一维映射是有损的,通过映射再还原回的经纬度坐标和原始输入的经纬度坐标存在一定的误差 。
3.4 geohash
文章插图
3.5 georadiusbymember : 查询指定元素附近的其它元素
文章插图
3.6 georadius
文章插图
【geohash算法的使用】
4 Redis Geo使用注意事项在一个地图应用中,车的数据、餐馆的数据、人的数据可能会有百万千万条,如果使用 Redis 的 Geo 数据结构,它们将全部放在一个 zset 集合中 。在 Redis 的集群环境中,集合可能会从一个节点迁移到另一个节点,如果单个 key 的数据过大,会对集群的迁移工作造成较大的影响,在集群环境中单个 key 对应的数据量不宜超过 1M,否则会导致集群迁移出现卡顿现象,影响线上服务的正常运行 。
所以,这里建议 Geo 的数据使用单独的 Redis 实例部署,不使用集群环境 。
如果数据量过亿甚至更大,就需要对 Geo 数据进行拆分,按国家拆分、按省拆分,按市拆分,在人口特大城市甚至可以按区拆分 。这样就可以显著降低单个 zset 集合的大小 。(注意:zset集合大小,进行合适地切分) 。
推荐阅读
- PC电源的迷思:电源真的是越重越好吗?
- 如何鉴别金丝皇菊的好坏
- 关于php中函数名,常量名,变量名大小写的问题介绍
- 白茶可以煮着喝吗 正确煮白茶的方法
- PID算法分析及参数调整
- 不用的凉席可以扔掉吗 凉席不用了能不能直接丢掉
- 垃圾桶做花盆 家里用的垃圾桶可以当花盆吗
- 代理ARP:合法的MAC欺诈技术
- 安心裤有正反吗 安心裤的前后怎么区别
- 工作3年和工作7年的程序员到底差在哪里?