Redis GEO地理位置应用
Redis 的五种数据结构各有特色,用对了才能发挥它的优势。很多人只用到了 String 和 Hash,却不知道 List、Set、ZSet 在特定场景下更合适。本文从应用场景出发,讲什么时候用什么类型。
一、GEO基本原理
#
1.1 底层实现
Redis GEO基于Sorted Set(ZSet)实现:
地理位置编码: |
#
1.2 GeoHash算法
GeoHash将地球表面递归划分为网格: |
二、GEO命令
#
2.1 添加位置
# GEOADD key longitude latitude member [longitude latitude member ...] |
#
2.2 获取位置
# GEOPOS key member [member ...] |
#
2.3 计算距离
# GEODIST key member1 member2 [M|KM|FT|MI] |
#
2.4 范围查询
# GEORADIUS key longitude latitude radius M|KM|FT|MI [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] |
#
2.5 基于成员的范围查询
# GEORADIUSBYMEMBER key member radius M|KM|FT|MI [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] |
#
2.6 获取GeoHash
# GEOHASH key member [member ...] |
三、Java中使用Redis GEO
#
3.1 Spring Data Redis
|
#
3.2 实际应用:附近的人
|
#
3.3 实际应用:配送范围
|
四、性能优化
#
4.1 数据分片
|
#
4.2 定期清理过期位置
|
#
4.3 使用辅助数据结构
|
五、注意事项
#
5.1 边界问题
GeoHash的边界问题: |
#
5.2 距离精度
# Redis GEO使用球面模型计算距离 |
#
5.3 大数量限制
单key存储的GEO位置数量: |
六、总结
| 命令 | 功能 | 时间复杂度 |
|---|---|---|
| GEOADD | 添加位置 | O(log n) |
| GEOPOS | 获取位置 | O(log n) |
| GEODIST | 计算距离 | O(log n) |
| GEORADIUS | 范围查询 | O(n+log m) |
| GEORADIUSBYMEMBER | 基于成员范围查询 | O(log n + m) |
| GEOHASH | 获取GeoHash | O(log n) |
GEO使用建议:
- 适合场景:附近查询、距离计算、范围判断
- 不适合场景:精确路径规划、复杂几何计算
- 分片策略:大数据量按区域分片
- 辅助结构:结合ZSet/Hash管理元数据
- 精度处理:短距离足够,长距离可二次精确
核心要点
String:简单的键值对,适合缓存、计数器
Hash:存储对象属性,适合用户信息、配置
List:有序列表,适合消息队列、最新列表
Set:无序去重,适合共同好友、抽奖
ZSet:有序集合,适合排行榜、积分系统
总结
选择合适的数据结构是使用 Redis 的关键。在实际项目中,根据业务需求选择合适的类型,可以提升性能和开发效率。