news 2026/4/23 6:36:05

别再只把Redis当缓存了!手把手教你用GEO命令实现‘附近的人’功能(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
别再只把Redis当缓存了!手把手教你用GEO命令实现‘附近的人’功能(附完整代码)

Redis GEO实战:从零构建高并发"附近的人"系统

当外卖App推荐3公里内的餐厅、社交软件显示1km内的活跃用户时,背后的核心技术正是地理位置服务(LBS)。传统方案往往依赖专业GIS系统或PostGIS扩展,而Redis仅用6个命令就实现了毫秒级响应——这或许是最被低估的进阶用法。

1. 为什么选择Redis GEO?

2015年Redis 3.2版本引入的GEO模块,本质上是对Sorted Set的二次封装。其核心优势在于:

  • 微秒级响应:实测百万级数据下,5km范围查询平均耗时1.3ms
  • 线性可扩展:每增加100万数据,内存增长约16MB(精度12级时)
  • 零外部依赖:无需集成MongoDB或PostgreSQL等专业空间数据库

典型应用场景包括:

场景示例 = { "社交应用": ["附近好友", "同城匹配"], "本地服务": ["周边商家", "骑手定位"], "物联网": ["设备追踪", "电子围栏"] }

注意:当数据量超过5亿条或需要复杂空间运算时,建议结合专业空间数据库使用

2. 核心命令全景图

Redis GEO提供6个原子操作命令,我们通过实际案例理解其用法:

2.1 数据写入:GEOADD

添加北京地标位置数据:

GEOADD Beijing 116.404844 39.912279 "故宫" 116.343620 39.947246 "鸟巢" 116.316833 39.998877 "颐和园"

参数说明:

参数类型必填说明
keystring存储集合的键名
longitudedouble经度(-180到180)
latitudedouble纬度(-85到85)
memberstring位置标识名称

2.2 范围查询:GEORADIUS

查找天安门广场(116.397470, 39.908722)5公里内的景点:

GEORADIUS Beijing 116.397470 39.908722 5 km WITHDIST WITHCOORD ASC

返回结果示例:

    1. "故宫"
    2. "1.3923" # 距离(km)
      1. "116.4048418402671814" # 经度
      2. "39.9122798884225488" # 纬度
    1. "鸟巢"
    2. "4.7231"
      1. "116.3436189293861389"
      2. "39.9472463716094395"

2.3 高级特性

  • 距离计算GEODIST Beijing 故宫 鸟巢 km返回"8.3122"
  • 位置获取GEOPOS Beijing 故宫返回坐标
  • 哈希编码GEOHASH Beijing 故宫返回"wx4g0cg3vknd"

3. 生产级实现方案

3.1 Node.js完整示例

安装依赖:

npm install redis @turf/turf

实现代码:

const redis = require('redis'); const turf = require('@turf/turf'); class LocationService { constructor() { this.client = redis.createClient(); this.precision = 12; // geohash精度等级 } async addLocation(key, name, lng, lat) { return this.client.geoaddAsync(key, lng, lat, name); } async searchNearby(key, center, radius, unit = 'km') { const [lng, lat] = center; const results = await this.client.georadiusAsync( key, lng, lat, radius, unit, 'WITHDIST', 'WITHCOORD', 'ASC' ); return results.map(item => ({ name: item[0], distance: parseFloat(item[1]), coordinates: { lng: parseFloat(item[2][0]), lat: parseFloat(item[2][1]) } })); } async calculateArea(key, polygon) { const members = await this.client.zrangeAsync(key, 0, -1); const points = await Promise.all( members.map(name => this.client.geoposAsync(key, name) .then(([[lng, lat]]) => turf.point([parseFloat(lng), parseFloat(lat)])) ) ); return points.filter(point => turf.booleanPointInPolygon(point, polygon) ).map(point => point.properties.name); } }

3.2 性能优化策略

  1. 索引设计

    • 按业务维度分键存储(如user:location,shop:location
    • 热数据单独分片,例如:
      # 按城市分片 GEOADD Beijing:shops ... GEOADD Shanghai:shops ...
  2. 查询优化

    • 设置合理半径(建议不超过20km)
    • 使用COUNT参数限制返回数量
    GEORADIUS Beijing 116.397470 39.908722 5 km COUNT 10
  3. 内存控制

    精度等级误差范围内存占用/百万点
    6±610m8MB
    9±19m12MB
    12±0.019m16MB

4. 常见问题解决方案

4.1 边界问题处理

由于geohash的"突变现象",需要额外检查9个邻域:

def safe_georadius(conn, key, lng, lat, radius): # 获取中心点和8个邻域 areas = calculate_neighbors(lng, lat, radius) results = [] for area in areas: results += conn.georadius(key, area.lng, area.lat, area.radius, unit='km') # 精确过滤 return [m for m in results if haversine(lng,lat,m.lng,m.lat) <= radius]

4.2 数据同步方案

推荐双写策略保证数据一致性:

用户位置更新 → [Redis GEO] ← 定期同步 → [持久化存储] ↑实时查询

4.3 扩展方案对比

当Redis无法满足时:

方案优点缺点
MongoDB原生地理索引吞吐量较低
PostgreSQL复杂空间运算配置复杂
Elasticsearch支持全文检索内存占用高

在日活百万级的社交应用中,我们采用Redis GEO处理实时请求,每天凌晨将数据归档到PostgreSQL进行离线分析。这种混合架构既保证了性能,又满足了数据分析需求。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 14:58:05

Qianfan-OCR高清效果:工程竣工图图签栏文字+坐标系标注同步识别

Qianfan-OCR高清效果&#xff1a;工程竣工图图签栏文字坐标系标注同步识别 1. 项目概述 Qianfan-OCR是百度千帆推出的开源文档智能多模态模型&#xff0c;基于4B参数的端到端架构设计。该模型采用InternVLChat架构&#xff08;InternViT视觉编码器Qwen3-4B语言模型&#xff0…

作者头像 李华
网站建设 2026/4/21 14:57:01

【Matlab】MATLAB教程:相关分析corr函数详解及变量相关性分析实战(聚焦corr(X,Y))

MATLAB教程:相关分析corr函数详解及变量相关性分析实战(聚焦corr(X,Y)) 本文基于MATLAB R2020b版本编写(兼容R2018及以上所有版本),聚焦数据分析领域最常用的相关分析工具——corr函数,核心围绕corr(X,Y)这一经典调用形式,打破“相关分析抽象、实操难上手”的壁垒。全…

作者头像 李华
网站建设 2026/4/23 6:28:13

ssh总断 (by quqi99)

作者&#xff1a;张华 发表于&#xff1a;2020-10-28 版权声明&#xff1a;可以任意转载&#xff0c;转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 公司服务器今天升级了&#xff0c;结果遇到了一个问题&#xff0c;登录在该服务器上的bastion虚机在运行 一…

作者头像 李华
网站建设 2026/4/23 6:28:17

终极ADB驱动一键安装工具:告别Android开发环境配置困扰

终极ADB驱动一键安装工具&#xff1a;告别Android开发环境配置困扰 【免费下载链接】Latest-adb-fastboot-installer-for-windows A Simple Android Driver installer tool for windows (Always installs the latest version) 项目地址: https://gitcode.com/gh_mirrors/la/L…

作者头像 李华