Redis Geo 实战:深入探索附近的人、LBS 场景与 Geohash 原理

发布时间:2026/10/27 13:50:50

Redis Geo 实战:深入探索附近的人、LBS 场景与 Geohash 原理 一、Redis Geo 概述1.1 Redis Geo 是什么Redis Geo 是 Redis 3.2 版本引入的地理位置数据结构用于存储地理位置信息并进行相关计算。它基于有序集合(Sorted Set)实现通过 Geohash 算法将二维的经纬度坐标转换为一维的字符串从而能够高效地实现地理位置相关的操作。1.2 Geo 数据结构介绍Redis Geo 使用有序集合(Sorted Set)来存储地理位置数据其中成员(member)为位置名称分数(score)为通过 Geohash 算法编码后的位置值。这种结构使得 Redis 能够利用有序集合的高效特性来处理地理位置数据。1.3 Redis Geo 应用场景概述Redis Geo 主要应用于以下场景附近的人功能商家推荐系统地理围栏应用实时位置追踪路径规划与导航二、附近的人实现原理2.1 基本实现思路实现附近的人功能的基本思路是存储用户的地理位置信息计算目标位置与用户当前位置的距离筛选出在一定范围内的用户2.2 GEOADD 命令介绍GEOADD 命令用于向 Geo 集合中添加地理位置信息其语法为GEOADD key longitude latitude member [longitude latitude member ...]例如GEOADD user_locations 116.404 39.915 user1 116.407 39.918 user22.3 GEOHASH 命令介绍GEOHASH 命令用于将地理位置信息编码为 Geohash 字符串其语法为GEOHASH key member [member ...]例如GEOHASH user_locations user1 user22.4 GEODIST 命令介绍GEODIST 命令用于计算两个地理位置之间的距离其语法为GEODIST key member1 member2 [unit][unit] 参数可选包括meters米kilometers千米miles英里feet英尺2.5 GEOSEARCH 命令介绍GEOSEARCH 命令用于查找指定范围内的地理位置信息其语法为GEOSEARCH key FROMLONLAT longitude latitude BYRADIUS radius unit [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]例如GEOSEARCH user_locations FROMLONLAT 116.404 39.915 BYRADIUS 1 km WITHDIST COUNT 5三、LBS 场景实战3.1 附近的人功能实现3.1.1 实现流程用户位置更新使用 GEOADD 存储用户位置用户查询附近的人使用 GEOSEARCH 查询指定范围内的用户返回结果展示给用户3.1.2 代码实现import redis # 连接 Redis r redis.Redis(hostlocalhost, port6379, db0) def add_user_location(user_id, longitude, latitude): 添加用户位置信息 r.geoadd(user_locations, longitude, latitude, user_id) def get_nearby_users(user_id, radius1, unitkm): 获取附近的人 # 获取当前用户位置 user_location r.geopos(user_locations, user_id) if not user_location: return [] longitude, latitude user_location[0] # 查询附近的人 nearby_users r.geosearch(user_locations, fFROMLONLAT {longitude} {latitude}, fBYRADIUS {radius} {unit}, WITHDIST, COUNT, 10) # 格式化返回结果 result [] for user in nearby_users: user_id user[0] distance user[1] result.append({ user_id: user_id, distance: distance }) return result3.2 商家推荐系统3.2.1 实现思路商家推荐系统可以根据用户当前位置推荐附近的商家提高用户体验和转化率。3.2.2 代码实现import redis # 连接 Redis r redis.Redis(hostlocalhost, port6379, db0) def add_shop_location(shop_id, longitude, latitude, category): 添加商家位置信息 r.geoadd(fshops:{category}, longitude, latitude, shop_id) def get_nearby_shops(user_id, category, radius5, unitkm): 获取附近的商家 # 获取用户位置 user_location r.geopos(user_locations, user_id) if not user_location: return [] longitude, latitude user_location[0] # 查询附近的商家 nearby_shops r.geosearch(fshops:{category}, fFROMLONLAT {longitude} {latitude}, fBYRADIUS {radius} {unit}, WITHCOORD, WITHDIST, WITHHASH) # 格式化返回结果 result [] for shop in nearby_shops: shop_id shop[0] distance shop[1] coordinates shop[2] result.append({ shop_id: shop_id, distance: distance, coordinates: coordinates }) return result3.3 地理围栏应用地理围栏(Geofencing)是一种基于地理位置的技术可以在特定地理边界内触发相应操作。3.3.1 实现思路定义地理围栏的边界点用户进入或离开围栏时触发事件执行相应的业务逻辑3.3.2 代码实现import redis import math # 连接 Redis r redis.Redis(hostlocalhost, port6379, db0) def is_point_in_polygon(point, polygon): 判断点是否在多边形内 x, y point n len(polygon) inside False j n - 1 for i in range(n): xi, yi polygon[i] xj, yj polygon[j] if ((yi y) ! (yj y)) and (x (xj - xi) * (y - yi) / (yj - yi) xi): inside not inside j i return inside def check_geofence(user_id, fence_id): 检查用户是否在地理围栏内 # 获取用户位置 user_location r.geopos(user_locations, user_id) if not user_location: return False longitude, latitude user_location[0] user_point (longitude, latitude) # 获取围栏边界点 fence_points r.lrange(fgeofence:{fence_id}, 0, -1) polygon [] for point in fence_points: lon, lat map(float, point.split(,)) polygon.append((lon, lat)) # 判断是否在围栏内 return is_point_in_polygon(user_point, polygon)3.4 实时位置追踪实时位置追踪功能可以实时显示用户或车辆的移动轨迹。3.4.1 实现思路定期更新用户位置保存历史轨迹实时推送位置更新3.4.2 代码实现import redis import time from threading import Thread # 连接 Redis r redis.Redis(hostlocalhost, port6379, db0) def update_user_location(user_id, longitude, latitude): 更新用户位置 # 添加当前位置 r.geoadd(user_locations, longitude, latitude, user_id) # 保存到历史轨迹 timestamp int(time.time()) r.zadd(ftrajectory:{user_id}, {f{longitude},{latitude}: timestamp}) def track_user_location(user_id, interval5): 追踪用户位置 while True: # 模拟获取用户位置 # 实际应用中应从 GPS 设备或移动端获取 longitude 116.404 (time.time() % 100) * 0.001 # 模拟移动 latitude 39.915 (time.time() % 100) * 0.001 update_user_location(user_id, longitude, latitude) time.sleep(interval) def get_user_trajectory(user_id, start_time, end_time): 获取用户轨迹 trajectory r.zrangebyscore(ftrajectory:{user_id}, start_time, end_time, withscoresTrue) result [] for point, timestamp in trajectory: lon, lat map(float, point.decode().split(,)) result.append({ longitude: lon, latitude: lat, timestamp: timestamp }) return result # 启动位置追踪线程 # Thread(targettrack_user_location, args(user1,)).start()四、Geohash 底层原理4.1 Geohash 算法原理Geohash 是一种将二维经纬度坐标编码成一维字符串的算法。其基本原理是将地球划分为多个矩形区域对每个区域进行递归细分为每个细分区域分配一个编码将多个编码组合成最终的 Geohash 字符串4.2 经纬度与 Geohash 转换4.2.1 编码过程将经度范围[-180, 180]和纬度范围[-90, 90]分别映射到[0, 1]交替对经度和纬度进行二分处理根据落在哪个区间选择 0 或 1将二进制结果转换为 base32 编码4.2.2 解码过程将 base32 编码转换为二进制交替解码为经度和纬度的二进制表示将二进制映射回经纬度范围计算中心点的经纬度坐标4.3 Geohash 精度与优化Geohash 的精度取决于编码的长度1位约5000km×5000km2位约1250km×625km3位×156km4位×39km5位×4.9km6位×1.2km7位×153m8位×19m9位×2.4m10位×60cm4.3.1 精度选择策略根据应用场景选择合适的 Geohash 精度城市级别5-6位区域级别7-8位街道级别9-10位4.3.2 优化策略前缀匹配优化利用 Geohash 的前缀特性快速筛选候选点多级索引结合不同精度的 Geohash 进行多级索引内存优化使用更紧凑的数据结构存储 Geohash4.4 Geohash 的局限性4.4.1 边界问题Geohash 在边界附近可能出现错误特别是在赤道和本初子午线附近。4.4.2 形状畸变在高纬度地区相同长度的 Geohash 代表的实际距离差异很大。4.4.3 邻接关系相邻的 Geohash 不一定表示地理位置相邻尤其是在编码长度较短时。五、最佳实践与优化5.1 性能优化策略5.1.1 合理使用索引为高频查询的地理位置建立索引使用复合索引优化多条件查询5.1.2 批量操作使用 GEOADD 批量添加位置数据使用 GEOSEARCH 批量查询位置信息5.1.3 数据分片按地理位置范围进行分片使用一致性哈希算法分配数据5.2 数据一致性保障5.2.1 事务处理使用 Redis 事务确保位置更新的原子性MULTI GEOADD key lon lat member other commands EXEC5.2.2 数据持久化启用 RDB 持久化配置 AOF 持久化设置合理的持久化策略5.3 扩展性设计5.3.1 读写分离使用 Redis Cluster 实现读写分离配置主从复制5.3.2 多级缓存使用本地缓存减少 Redis 访问实现缓存穿透和缓存雪崩防护5.3.3 水平扩展使用 Redis Cluster 进行水平扩展合理分配分片策略
延伸阅读

更多相关文章

2026/10/27 0:15:34

网易2019秋招编程真题全解析:算法思路与刷题避坑指南

这段时间陆陆续续有学弟学妹来问我,说网易2019秋季校园招聘编程题真题集合到底该怎么刷,网上翻来翻去就是几份题目列表,没有详细的解题思路,刷完还是心里没底。这个问题我确实有点发言权,当年秋招我把这套题完整刷过两…

2026/10/27 21:05:34

ADB与Fastboot实战指南:从环境搭建到刷机救砖的完整解决方案

简介:Android Debug Bridge(ADB)和Fastboot是Android开发与设备管理的核心工具链,它们构建了计算机与移动设备之间的调试与通信桥梁。ADB基于客户端-服务器架构运行,允许在设备开机状态下执行应用安装、文件传输、Shel…

2026/10/27 21:04:29

图论最短路径算法精讲:从Dijkstra到Floyd的建模实战与竞赛应用

1. 项目概述:从“找路”到“建模”的思维跃迁“图论最短路径问题”,这八个字对于初次接触数学建模的同学来说,可能既熟悉又陌生。熟悉在于,“最短路径”这个概念我们几乎每天都在用——用手机地图导航找一条不堵车的最快回家路线&…

2026/10/28 8:28:17

Django与OpenCV实现指纹识别系统的开发实践

1. 项目概述:当Django遇上指纹识别指纹识别技术从刑侦领域走向民用已经二十余年,如今我们手机上的指纹解锁响应时间已经可以做到300毫秒以内。但很多人不知道的是,搭建一个基础指纹识别系统,用PythonDjango的组合只需要不到200行核…

2026/10/28 8:28:17

用本体论拆解Microsoft Fabric:统一数据分析平台的能力与核心概念

我很少用“本体论”这种词去聊一个SaaS平台,但Fabric确实值得这么拆一次。Fabric是微软围绕统一数据底座推出的企业级数据分析平台,它的“本体”不是某个单机软件,而是一套把存储、集成、计算、分析和治理串成一条完整链路的数据基础体系。Fa…

2026/10/28 8:28:17

代理式AI如何重构咨询业:从信息壁垒到人机协同新范式

去年接了一个供应链优化的咨询项目,做到中期汇报时,客户方的数字化负责人忽然问了我一句:你们提出的四个改善方向,我们内部用代理式 AI 跑了两周,也得到差不多的排序。他说得很客气,但我听出了潜台词&#…

2026/10/28 8:28:17

边缘AI模型分割:核心策略与实战优化指南

1. 边缘AI部署的核心挑战与模型分割价值当我们在智能摄像头里运行人脸识别、在工业传感器上做异常检测、或者在车载系统实时处理路况时,传统云计算"数据上传-中心计算-结果返回"的模式已经捉襟见肘。去年参与某智慧园区项目时,我们曾测试过将2…

2026/10/28 8:28:17

文件签名校验工具:原理、技术与AI增强实践

1. 为什么我们需要文件签名校验工具在数字化办公环境中,文件传输已成为日常工作的基础环节。但你是否遇到过这样的场景:从官网下载的安装包运行时被杀毒软件拦截,团队共享的设计稿在传输后出现像素错位,或者更糟——重要合同文档在…

2026/10/28 8:23:17

深圳“人工智能+”先进制造业行动计划:AI落地制造的关键路径

前阵子产业群里有人转发了一份文件:《深圳市“人工智能”先进制造业行动计划(2026-2027年)》。刚看到标题,我第一反应是又一份产业规划,这类文件一年能见十几份。但把公开信息和深圳近几轮制造业数字化转型的动作对照起…

2026/10/27 14:24:03

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/27 9:34:54

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/28 0:02:13

Python股票自动交易系统源码解析:从行情获取到风控的完整链路

简介:这份资源是面向高校计算机、金融相关专业毕业设计场景的完整项目源码包,主题为基于Python的股票自动交易系统,适合需要完成毕设选题、课程设计或自学金融量化交易开发的学生与开发者参考。压缩包共收录687个文件,整体约14.93…

2026/10/28 0:02:13

视酷酷信IM源码部署指南:Java 17+MySQL 8.0.33实战配置

简介:这是一套2024年亲测可部署的视酷酷信IM即时通讯系统源码,面向具备Java、OC、C#及Vue开发能力的技术人员,解决私有化即时通讯平台快速搭建与二次定制需求,尤其适用于需集成商城、保障数据主权的中小型企业或独立开发者。资源共…

2026/10/28 0:02:13

Python爬取百度迁徙数据:接口解析、批量采集与避坑指南

简介:这份资源是一个用Python爬取百度迁徙数据的脚本压缩包,面向具备Python基础、希望入门网络爬虫与数据解析的开发者,解决按日期获取全国热门城市人口迁徙数据的问题。包内共1个文件,为单个py脚本,压缩包约1KB&#…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑