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/28 9:22:38

网易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 9:23:49

虚拟世界法律框架:智能合约与数字治理实践

1. 项目背景与核心价值"数字创世纪:在虚拟世界重写人类法典"这个项目名称本身就蕴含着深刻的时代命题。当元宇宙、数字孪生等技术从概念走向落地,我们突然发现:虚拟世界正在形成一套独立于现实社会的运行规则。去年某知名虚拟平台爆…

2026/10/28 9:23:49

智能运维AIOps核心技术解析与行业实践

1. 智能运维的行业现状与核心价值2008年亚马逊的一次服务器宕机事件,让全球首次意识到传统运维模式的脆弱性——仅31分钟的故障导致公司损失约6600万美元。这个标志性事件直接催生了智能运维(AIOps)概念的兴起。如今在数字化转型浪潮下&#…

2026/10/28 9:23:49

子目标感知记忆图:面向GUI智能体的记忆框架

子目标感知记忆图:面向GUI智能体的记忆框架 原文网页:https://arxiv.org/html/2610.31307v1 PDF链接:https://arxiv.org/pdf/2610.31307v1 arXiv编号:arXiv:2610.31307v1 [cs.AI] 摘要 GUI智能体通过与移动端图形界面交互完成复杂…

2026/10/28 9:23:49

AgentMoCo:面向长视界智能体的动量对比记忆优化框架

AgentMoCo:面向长视界智能体的动量对比记忆优化框架 原文网页:https://arxiv.org/html/2610.31355v1 PDF链接:https://arxiv.org/pdf/2610.31355v1 arXiv编号:arXiv:2610.31355v1 [cs.AI] 摘要 长视界工具调用智能体在执行上百步复…

2026/10/28 9:18:43

电子电路设计实用手册:从运放到电源的工程实战参考

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

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
免费获取方案
☎咨询二维码 ☎ ↑