附近的人功能如何设计
问题理解先对齐需求面试官您好关于“附近的人”功能我先明确几个核心点用户量级千万级DAU按大厂标准聊实时性位置要相对新鲜但不必强实时可以容忍几秒到几分钟的延迟核心操作上传坐标、搜索附近的人、分页、按距离排序隐含需求高并发、低延迟、数据一致性不必强求可用最终一致核心需求拆解 需求类型 具体要求 技术指标功能需求 查看指定范围内的用户按距离排序支持性别 / 年龄筛选实时更新位置 查询延迟 100ms支持百万级同时在线非功能需求 隐私保护高并发数据一致性容灾备份 位置精度误差 50m可用性 99.99%整体架构设计 ️image核心流程用户上线 / 移动时上报经纬度到位置服务位置服务更新数据库和缓存用户查询附近的人时先查缓存缓存 miss 再查数据库结果按距离排序并过滤后返回给用户核心技术方案 ⚙️地理位置索引GeoHash 算法 这是实现附近的人最核心的技术将二维经纬度编码为一维字符串编码长度越长精度越高6 位≈61m7 位≈76m相邻区域的 GeoHash 前缀相同查询时只需匹配相同前缀的用户再计算精确距离示例北京天安门的 GeoHash 是wx4g0ec1附近 500 米内的用户 GeoHash 都以wx4g0e开头。数据存储方案 Redis Geo首选方案Redis 3.2 原生支持 Geo 命令GEOADD添加用户位置GEORADIUS查询指定半径内的用户GEODIST计算两个用户之间的距离优点高性能、支持原子操作、自带排序MySQL 空间索引作为持久化存储使用POINT类型存储经纬度创建SPATIAL INDEX加速查询用于 Redis 缓存失效后的兜底查询为什么首选 Redis Geo“附近的人”本质是一个 LBS基于位置服务的地理位置检索典型需求是传入一个坐标lat, lng和半径 r返回半径内的所有用户并按距离排序。我选 Redis Geo原因很简单方案 核心数据结构 优缺点MySQL 经纬度字段 球面距离公式 普通索引 需全表扫无法利用索引千万级直接跪 ❌MySQL Spatial (R-tree) 空间索引 边界查询可用但排序和距离计算仍较重高并发扛不住 ❌MongoDB 2dsphere Geohash B树 功能可以但生态和运维成本大调用链路长 ⚠️Redis Geo ZSET Geohash 原生内存操作读写极快单机10w QPS ✅Redis Geo 底层是把经纬度编码成 Geohash 字符串塞进一个 Sorted Set。Score 就是这个 Geohash 转化成的 52 位整数。这样一来附近的点其 Geohash 前缀相同落在 ZSET 的相邻区间范围查询就是 ZSET 的 ZRANGEBYSCORE时间复杂度 O(log(N)M)非常快。我画个简单的结构图image高性能查询优化 是否用户查询请求缓存是否命中?直接返回缓存结果查询Redis Geo计算精确距离并排序过滤用户信息更新缓存缓存预热热门区域提前加载用户位置到 Redis分页查询每次只返回前 50-100 个用户避免数据量过大结果缓存查询结果缓存 10-30 秒减轻数据库压力异步更新用户位置更新通过 Kafka 异步处理不阻塞主流程4. 核心实现Redis 命令与编码细节业务层就这么几条命令① 用户位置更新GEOADD nearby:users 116.404 39.915 user:1001每次用户打开 App 或移动一定距离后上报我们实时执行这条。高并发下用 Pipeline 或 Redis Cluster 的 hash tag 保证同一个用户落在相同分片。② 搜索附近的人GEORADIUS nearby:users 116.405 39.916 5 km WITHDIST COUNT 20 ASC返回距离、用户ID按距离升序带分页Redis 没有游标但我们用 COUNT 和客户端保存的 offset 做逻辑分页。更深层的分页不推荐通常限制前 N 页比如 200 条。③ 扩展性考虑如果用 Redis ClusterGeo 相关的 key 必须用 hash tag 保证在一个节点GEOADD {nearby}:users …搜索时也这样指定。同时我们按城市或大区域预分片避免单个 ZSET 过大建议一个 key 内用户数 50 万过大用多 key 分片。 整体架构带图更直观image位置服务 无状态方便水平扩展。Redis Geo 分片比如 {beijing}:nearby:users{shanghai}:nearby:users。搜索完后得到一堆 user id批量去 Redis 缓存里拿头像昵称缓存未命中穿透到 MySQL。用户位置更新同时异步发一条 MQ用于轨迹存储、风控等。进阶考虑与优化 隐私保护 用户可随时开启 / 关闭 “附近的人” 功能位置信息只保留最近 24 小时过期自动删除支持模糊位置显示如 “距离 100 米内” 而非精确坐标禁止非好友查看用户详细位置高并发处理 ⚡读写分离读操作走 Redis写操作异步同步到 MySQL分片存储按 GeoHash 前缀分片将不同区域的用户分散到不同 Redis 节点限流保护限制单个用户每秒查询次数防止恶意刷接口容灾与扩展 ️Redis 集群部署主从复制 哨兵模式保证高可用MySQL 主从复制读写分离多机房部署异地容灾支持水平扩展用户量增加时只需添加 Redis 节点分页的坑GEORADIUS 没有服务端游标所以若每次都传 offset 200其实 Redis 内部会计算全部结果然后截取浪费 CPU。解决业务限定最大翻页比如第 10 页之后直接拒绝或在前端交互上做无限滚动加载一小段同时缓存“看过的人”去重。热点数据某个城市的 Geo Key 可能成为热点比如北京。方案同一城市内再按地理位置做二级分片{beijing:1}:nearby{beijing:2}:nearby查询时根据请求坐标决定查哪个分片和相邻分片Geohash 边界。主从读分离本地缓存常用搜索结果。6. 用户频繁移动不能每次手机抖一下就更新 Redis。客户端做阈度上报移动超过 50 米或超过 2 分钟才上传一次。踢除离线用户Redis 里只留活跃用户。用 TTL不行Geo 不能直接对 member 设过期。我们的做法额外维护一个 online:users 的 ZSET用最后心跳时间做 score。定时任务扫出过期用户一并从 Geo Key 和在线 Key 中删除。或者 Geo 成员设一个“逻辑过期”时间戳在 Value 中这里 Redis Geo 只存 member 是 user:id不能存额外字段所以需要另一个 key 存时间异步清理。8. 一些深层追问的思考Q: 如果不满足 Redis Geo比如要在附近人中按兴趣过滤那就需要 Geo 提供候选集再在应用层做交集。或用 MongoDB 多条件索引但会牺牲一些性能。大厂可能会自研 LBS 引擎基于 Geohash 建立倒排索引。Q: 数据倾斜怎么处理热点城市多分片并且监控每个分片大小动态分裂。Q: 如何保证服务的最终一致性位置更新可接受短暂不一致。Redis 本身高性能做 AOF 持久化挂了从 RDB 恢复 用户心跳重建在线状态。总结 ✨“附近的人”核心就三句话用 Redis Geo 扛住海量位置读写底层 ZSET Geohash 精准索引。架构上做水平分片、按区域拆分 key避免大 key 和热点。用户状态、分页、业务过滤都做保护防止滥用和性能劣化。如果需要更高维度的组合查询可以引入 ES 的地理位置类型但单纯一个“附近”功能Redis Geo 是最轻量高性能的解法。这个设计方案以Redis Geo为核心结合 GeoHash 算法实现高效的地理位置查询通过缓存、异步更新、分片等技术保证高并发性能同时充分考虑了用户隐私保护和系统容灾能力。可以轻松支撑百万级同时在线用户查询延迟控制在 100ms 以内完全满足互联网大厂的业务需求。附近的人功能核心代码 技术难点全解 完全贴合大厂面试标准直接可背、可写、可讲代码简洁有亮点难点一针见血核心代码Java Redis Geo✨这是面试最加分、最能体现真实开发经验的代码基于 Spring Boot RedisTemplate 实现。依赖Spring Boot 环境org.springframework.boot spring-boot-starter-data-redis 2. 核心配置Redis 连接工厂 Configuration public class RedisConfig { Bean public RedisGeoCommands}4. 返回实体Datapublic class NearUserDTO {private Long userId;private Double distance; // 距离多少米// 可扩展昵称、头像、性别、年龄等}5. 位置更新GEOADD—— 附带 LUA 原子保活// 用户上报位置同时刷新在线心跳public void updateLocation(String userId, double lng, double lat) {String geoKey resolveGeoKey(lng, lat); // 按城市分片如 “{beijing}:nearby:users”String onlineKey “online:heartbeat”;long now System.currentTimeMillis();// 使用 Lettuce 异步 Pipeline 减少 RTT redisTemplate.executePipelined((RedisCallbackObject) connection - { byte[] geoKeyBytes geoKey.getBytes(); byte[] member userId.getBytes(); // GEOADD key longitude latitude member connection.geoCommands().geoAdd(geoKeyBytes, new Point(lng, lat), member); // 同时更新在线心跳 ZSETscore 当前时间戳 connection.zSetCommands().zAdd(onlineKey.getBytes(), now, member); return null; });}

相关新闻

2026亚洲EMBA性价比榜单:深耕实业的老板,认准这所资源强的亚洲EMBA

2026亚洲EMBA性价比榜单:深耕实业的老板,认准这所资源强的亚洲EMBA

【客观中立测评声明】本文为独立财经择校测评,无硬性广告植入,基于2026年最新院校公开数据,从民企经营视角拆解亚洲主流EMBA项目真实适配度,理性分析优劣,仅供企业创始人、高管择校参考。不少实体老板、科创企业实控人…

2026/7/23 21:45:40 阅读更多 →
适合科技公司高管的大湾区EMBA测评榜单:避开镀金陷阱,聚焦实干赋能

适合科技公司高管的大湾区EMBA测评榜单:避开镀金陷阱,聚焦实干赋能

【客观测评声明】本文为中立财经测评内容,无硬性广告植入,基于学费成本、课程落地性、学员圈层、长期赋能四大维度,针对大湾区主流EMBA项目做性价比分层,仅为科创企业创始人、民企高管择校提供客观参考。不少大湾区实业老板、科技…

2026/7/24 16:34:51 阅读更多 →
2026知名亚洲EMBA择校测评:民企老板高性价比榜单出炉

2026知名亚洲EMBA择校测评:民企老板高性价比榜单出炉

导语:深耕商科测评5年,见过太多民企老板读EMBA踩坑:高价入学后课程老旧不落地、圈层多为中层管理者无决策价值、所谓国际资源流于形式。本次立足实业视角,以四大核心维度客观测评知名亚洲EMBA项目,帮创业者精准避坑、理…

2026/7/24 5:38:04 阅读更多 →

最新新闻

Context Portal MCP服务器架构深度剖析:Python/FastAPI如何构建高效RAG后端

Context Portal MCP服务器架构深度剖析:Python/FastAPI如何构建高效RAG后端

Context Portal MCP服务器架构深度剖析:Python/FastAPI如何构建高效RAG后端 【免费下载链接】context-portal Context Portal (ConPort): A memory bank MCP server building a project-specific knowledge graph to supercharge AI assistants. Enables powerful R…

2026/7/25 21:21:10 阅读更多 →
【AI批量翻译实战指南】:20年技术专家亲授5大避坑法则,90%团队忽略的自动化陷阱

【AI批量翻译实战指南】:20年技术专家亲授5大避坑法则,90%团队忽略的自动化陷阱

更多请点击: https://kaifayun.com 第一章:AI批量翻译的本质与技术演进全景 AI批量翻译并非简单地将单句翻译能力叠加,而是融合大规模并行处理、上下文感知建模与领域自适应的系统工程。其本质是构建一种可扩展、低延迟、高一致性语义映射管…

2026/7/25 21:21:10 阅读更多 →
大语言模型对齐调优中的偏见形成机制与缓解策略

大语言模型对齐调优中的偏见形成机制与缓解策略

最近在调试一个基于大语言模型的问答系统时,我遇到了一个有趣的现象:当我用“你觉得这个方案怎么样?”提问时,模型会根据我之前的发言倾向来调整回答。如果我先表达了对某个技术栈的偏好,模型就更可能迎合这种偏好&…

2026/7/25 21:21:10 阅读更多 →
录音棚级AI母带处理不是玄学!用FFT相位对齐+感知编码补偿,将AI音频失真率从8.3%压至0.47%

录音棚级AI母带处理不是玄学!用FFT相位对齐+感知编码补偿,将AI音频失真率从8.3%压至0.47%

更多请点击: https://codechina.net 第一章:录音棚级AI母带处理不是玄学!用FFT相位对齐感知编码补偿,将AI音频失真率从8.3%压至0.47% 传统AI音频生成在母带阶段常因频谱相位坍塌与编解码器感知建模偏差导致谐波畸变、瞬态模糊和立…

2026/7/25 21:21:10 阅读更多 →
oneAPI Math Library (oneMath)完全指南:从入门到精通的跨平台数学计算引擎

oneAPI Math Library (oneMath)完全指南:从入门到精通的跨平台数学计算引擎

oneAPI Math Library (oneMath)完全指南:从入门到精通的跨平台数学计算引擎 【免费下载链接】oneMKL oneAPI Math Library (oneMath) 项目地址: https://gitcode.com/gh_mirrors/on/oneMKL oneAPI Math Library (oneMath) 是一个开源的跨平台数学计算引擎&am…

2026/7/25 21:21:10 阅读更多 →
Flutter Admin图表组件全解析:数据可视化从未如此简单

Flutter Admin图表组件全解析:数据可视化从未如此简单

Flutter Admin图表组件全解析:数据可视化从未如此简单 【免费下载链接】flutter_admin Flutter Admin: 一个基于 Flutter 的后台管理系统、开发模板。A backend management system and development template based on Flutter 项目地址: https://gitcode.com/gh_m…

2026/7/25 21:20:10 阅读更多 →

日新闻

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了解决您的…

2026/7/25 0:00:35 阅读更多 →
C++ string类模拟实现:从深拷贝到内存管理的完整指南

C++ string类模拟实现:从深拷贝到内存管理的完整指南

1. 项目概述:为什么我们要“手撕”string类?在C的学习道路上,尤其是从C语言过渡到C的“初阶”阶段,string类绝对是一个绕不开的核心。标准库里的std::string用起来太方便了,、find、substr,几个操作符和函数…

2026/7/25 0:00:35 阅读更多 →
三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

1. 先搞清楚“三角洲寻宝鼠”到底是什么工具从名称来看,“三角洲寻宝鼠”更像是一个资源查找或文件检索类工具,而不是游戏或娱乐软件。这类工具的核心价值在于帮助用户快速定位特定资源,比如文档、图片、压缩包或特定格式的文件。如果你经常需…

2026/7/25 0:00:35 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/25 5:08:22 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/25 5:13:53 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 18:52:18 阅读更多 →

月新闻