自Redis 3.2开始,Redis基于geohash和有序集合提供了地理位置相关功能。Redis Geo模块包含了以下6个命令:
GEOADD: 将给定的位置对象(纬度、经度、名字)添加到指定的key;
GEOPOS: 从key里面返回所有给定位置对象的位置(经度和纬度);
GEODIST: 返回两个给定位置之间的距离;
GEOHASH: 返回一个或多个位置对象的Geohash表示;
GEORADIUS: 以给定的经纬度为中心,返回目标集合中与中心的距离不超过给定最大距离的所有位置对象;
GEORADIUSBYMEMBER: 以给定的位置对象为中心,返回与其距离不超过给定最大距离的所有位置对象。其中,组合使用GEOADD和GEORADIUS可实现“附近的人”中“增”和“查”的基本功能。
要实现微信中“附近的人”功能,可直接使用GEORADIUSBYMEMBER命令。其中“给定的位置对象”即为用户本人,搜索的对象为其他用户。
示例:
假设用户ID是33,经纬度位置是(116.054579, 39.030452),我们可以用一个 GEO 集合保存所有用户的经纬度,集合 key 是 users:locations。执行下面的这个命令,就可以把ID号为33的用户的当前经纬度位置存入GEO集合中:
GEOADD users:locations 116.034579 39.030452 33
当用户想要寻找自己附近的人时,就可以使用 GEORADIUS 命令。
例如,执行下面的命令,Redis 会根据输入的用户的经纬度信息(116.054579, 39.030452),查找以这个经纬度为中心的5公里内的用户信息。
GEORADIUS users:locations 116.054579 39.030452 5 km ASC COUNT 10
注意:
在一个地图应用中,车的数据、餐馆的数据、人的数据可能会有百万千万条,如果使用 Redis 的 Geo 数据结构,它们将全部放在一个 Sorted Set 集合中。
在 Redis 的集群环境中,集合可能会从一个节点迁移到另一个节点,如果单个 key 的数据过大,会对集群的迁移工作造成较大的影响,在集群环境中单个 key 对应的数据量不宜超过 1M,否则会导致集群迁移出现卡顿现象,影响线上服务的正常运行。
所以,这里建议 Geo 的数据使用单独的 Redis 实例部署,不使用集群环境。
如果数据量过亿甚至更大,就需要对 Geo 数据进行拆分,按国家拆分、按省拆分,按市拆分,在人口特大城市甚至可以按区拆分。这样就可以显著降低单个 Sorted Set 集合的大小。
网友回复
python如何实现torrent的服务端进行文件分发p2p下载?
如何在浏览器中录制摄像头和麦克风数据为mp4视频保存下载本地?
go如何编写一个类似docker的linux的虚拟容器?
python如何写一个bittorrent的种子下载客户端?
ai能通过看一个网页的交互过程视频自主模仿复制网页编写代码吗?
ai先写功能代码通过chrome mcp来进行测试功能最后ai美化页面这个流程能行吗?
vue在手机端上下拖拽元素的时候如何禁止父元素及body的滚动导致无法拖拽完成?
使用tailwindcss如何去掉响应式自适应?
有没有直接在浏览器中运行的离线linux系统?
nginx如何保留post或get数据进行url重定向?