[TOC] #### 1. 前言 --- 打开外卖 App,附近 3 公里的商家立刻列出来了,叫个网约车,附近的司机实时显示在地图上 这种 “附近的人/店/车” 功能,Redis 的 GEO 类型就能做,底层其实是 ZSet,用经纬度算距离 #### 2. 基本操作 --- 添加位置: ```bash geoadd shops 116.397128 39.916527 "shop:001" geoadd shops 116.405285 39.904989 "shop:002" ``` 算两个点之间的距离: ```bash geodist shops "shop:001" "shop:002" km ``` 以某个坐标为中心,找附近 3 公里内最近 10 个: ```bash georadius shops 116.397128 39.916527 3 km ASC COUNT 10 WITHCOORD WITHDIST ``` 以某个成员为中心,找附近: ```bash georadiusbymember shops "shop:001" 3 km ASC COUNT 10 ``` #### 3. 附近商家 --- 商家入驻时存坐标,用户打开 App 时查附近 ```python def add_shop(shop_id, lng, lat): redis.geoadd("shops", lng, lat, f"shop:{shop_id}") def find_nearby(lng, lat, radius=3): return redis.georadius( "shops", lng, lat, radius, unit="km", sort="ASC", count=10, withcoord=True, withdist=True ) ``` #### 4. 底层原理 --- GEO 用 GeoHash 把二维经纬度编码成一个一维数值,存到 ZSet 的 score 里 附近的点编码值也接近,所以用 ZSet 的范围查询就能找到附近的成员,精度大约 1 米,对大多数场景够用了 #### 5. 注意事项 --- 经纬度有范围:经度 -180~180,纬度 -85~85,超出会报错 同一个 member 再次 geoadd 会更新坐标,不会重复,百万级商家没问题,亿级要考虑分片 #### 6. 本文小结 --- 小总结: + GEO 存经纬度,算距离,查附近范围 + geoadd 添加,geodist 算距离,georadius 查附近 + 底层 ZSet + GeoHash 编码 + 适合:附近商家、骑手定位、打车软件 + 精度约 1 米,百万级数据没问题 到这里,第二阶段 “核心数据结构” 全部完成 五大数据结构 + Bitmap + HyperLogLog + GEO,Redis 的数据类型你已经全认识了 下一讲进入第三阶段高并发实战,来看缓存穿透到底怎么解决