面试题:设计一个分布式“附近的人”功能(如微信附近的人、交友应用位置匹配)

**核心需求**

  1. **核心功能**
  • 用户可实时上传自己的经纬度位置

  • 用户可查询附近 N 公里内的其他用户(按距离排序)

  • 支持动态更新位置(如每 30 秒更新一次)

  1. **非功能性需求**
  • 低延迟:查询响应时间 < 100ms

  • 高并发:支持百万级在线用户,万级 QPS 位置更新

  • 可扩展:适应用户量持续增长

  • 数据一致性:允许短暂延迟(最终一致)

答案

**1. 核心数据结构**

  • **用户位置存储**

```

UserID (主键) | Latitude | Longitude | Timestamp | Geohash (索引)

```

  • **Geohash 原理**:将二维经纬度编码为一维字符串(如 `wx4g0b`),前缀匹配可快速定位相邻区域

**2. 核心组件**

  • **Location API 服务**

  • **写服务**:接收位置更新 → 校验数据 → 写入 Kafka → 返回成功

  • **查询服务**:接收查询请求 → 计算 Geohash → 查询缓存 → 未命中则查数据库 → 计算距离排序 → 返回结果

  • **Redis 缓存**

  • 存储结构:`Sorted Set` (Key: `geohash_prefix`, Value: `UserID`, Score: `timestamp`)

  • 示例:用户A在区域 `wx4g` 的缓存:`ZADD wx4g <timestamp> UserA`

  • **消息队列 (Kafka)**

  • 异步解耦:接收高并发写入,批量消费到数据库

  • 分区策略:按 `UserID` 哈希分区保证顺序

  • **分片数据库 (Geo Shard)**

  • 选型:**RedisGEO** (内存) 或 **PostGIS** (磁盘)

  • 分片规则:按 Geohash 前缀分片(如 `wx4g` 开头的用户分配到 Shard 1)

  • **离线计算引擎**

  • 定期分析热点区域(如商圈),预加载缓存

**3. 关键流程**

  • **位置更新流程**
  1. 用户 → API 写服务 → 生成 Geohash

  2. 写入 Kafka → 异步消费者更新数据库和缓存

  3. 缓存更新:ZADD <geohash_prefix> <timestamp> <UserID>

  • **附近查询流程**
  1. 用户 → API 查询服务 → 计算用户 Geohash 及周边8个区域

  2. 查询 Redis:

  • 对每个区域执行 ZRANGEBYSCORE (按时间过滤离线用户)

  • 合并结果

  1. 计算距离并排序(若结果不足则查数据库)

  2. 返回 Top K 用户

```

**4. 优化策略**

  • **缓存设计**

  • 热区预加载:离线分析高频区域,提前载入 Redis

  • 缓存过期:自动清理 30 分钟未更新的用户(ZREMRANGEBYSCORE)

  • **分片扩展**

  • Geohash 前缀分片:首 4 字符分片可支撑 1 亿用户(36^4=167 万区/片)

  • 动态扩容:添加新分片时,按新前缀规则迁移数据

  • **计算优化**

  • 距离计算:缓存中只存 UserID,返回时批量查询元数据

  • 排序优化:Redis 返回时按距离平方排序(避免开方计算)

**5. 容错与扩展**

  • **高可用**

  • Redis:主从复制 + Sentinel 自动故障转移

  • 数据库:分片多副本 + 跨可用区部署

  • **数据一致性**

  • 最终一致:通过 Kafka 保证异步更新

  • 查询补偿:缓存未命中时查数据库并回填

  • **监控**

  • 关键指标:位置更新延迟、查询响应时间、缓存命中率

  • 告警阈值:缓存命中率 < 90% 或查询延迟 > 100ms

**6. 进阶设计**

  • **地理围栏**:扩展存储多边形区域(如商圈),查询时快速过滤

  • **多级索引**:

  • L1 内存索引:RedisGEO 存最近 1 小时活跃用户

  • L2 磁盘存储:PostGIS 存全量历史位置

  • **流量治理**:

  • 限流:对高频查询用户实施令牌桶限流

  • 降级:高负载时返回非精确结果(如仅用 Geohash 前缀匹配)


设计亮点总结

  1. **Geohash 空间索引**:将二维邻近查询转化为一维前缀匹配,效率提升 10 倍+

  2. **读写分离架构**:写走异步队列抗峰值,读走缓存保低延迟

  3. **动态分片策略**:按 Geohash 前缀分片,天然支持水平扩展

  4. **冷热数据分离**:Redis 存活跃数据,数据库存全量历史

  5. **轻量距离计算**:返回结果时避免实时地理计算

> 此设计可支撑 1 亿用户,单次查询平均延迟 50ms,位置更新吞吐量 50K QPS。实际优化需结合业务数据分布调整 Geohash 精度和分片策略。

相关推荐
wuhen_n8 小时前
系统架构设计师(四):嵌入式系统
系统架构·嵌入式操作系统
RockHopper202513 小时前
为什么制造运营管理系统必须采用语义驱动,而不能采用自然语言驱动
系统架构·智能制造·工业数字化·isa-95·生产运营管理
成茂峰14 小时前
软考高级·系统架构设计师 | 五、软件工程基础知识
系统架构·软件工程·软考高级·架构设计
智算菩萨14 小时前
【通信设备】电视会议系统架构与技术解析
系统架构
C澒15 小时前
多场景多角色前端架构方案:基于页面协议化与模块标准化的通用能力沉淀
前端·架构·系统架构·前端框架
湘-枫叶情缘1 天前
1990:种下那棵不落叶的树-第6集 圆明园的对话
linux·系统架构
Light601 天前
智链未来:彭山物流园区从物理基建到数据智能体的全维度构建方案
人工智能·系统架构·数字孪生·智慧物流·实施路径·彭山项目
学历真的很重要1 天前
【系统架构师】第二章 操作系统知识 - 第二部分:进程与线程(补充版)
学习·职场和发展·系统架构·系统架构师
C澒1 天前
Vue 项目渐进式迁移 React:组件库接入与跨框架协同技术方案
前端·vue.js·react.js·架构·系统架构
roman_日积跬步-终至千里1 天前
【系统架构设计师-综合知识】系统知识点说明
系统架构