哈希算法题目:实现一个基于哈希的分布式实时游戏排行榜系统(支持分数更新、Top K 查询和分段范围查询)
字数 1938 2025-12-07 17:14:11
哈希算法题目:实现一个基于哈希的分布式实时游戏排行榜系统(支持分数更新、Top K 查询和分段范围查询)
题目描述:
设计一个支持高并发、可扩展的分布式实时游戏排行榜系统。要求实现以下功能:
- 分数更新:给定用户ID和新的分数,如果用户不存在则新增记录,如果已存在则更新分数(分数只增不减)。
- Top K 查询:返回当前分数最高的 K 个用户及其分数。
- 分段范围查询:查询某个分数区间内的用户数量和列表(例如分数在 [1000, 2000] 的所有用户)。
系统需支持海量用户(例如千万级)和高并发更新/查询。请基于哈希结合其他数据结构设计解决方案,并解释其分布式扩展方法。
解题过程
步骤1:分析需求与核心挑战
- 实时性:分数更新和查询需在低延迟内完成。
- 高分查询效率:Top K 查询需高效,避免全量排序。
- 范围查询:需快速获取任意分数区间的用户。
- 分布式扩展:数据量可能单机无法容纳,需分片存储。
- 一致性:分数只增不减,避免因网络延迟导致分数回退。
步骤2:核心数据结构设计
使用 哈希表 + 跳表(Skip List) 组合:
- 哈希表:键为用户ID,值为分数。用于 O(1) 时间更新和获取单个用户分数。
- 跳表:按分数从大到小排序(分数相同可按用户ID排序),每个节点存储(分数, 用户ID)。支持:
- O(log N) 插入/更新(因分数只增不减,可先删除旧分数节点,再插入新节点)。
- O(log N + K) 的 Top K 查询:从跳表头部向后遍历 K 个节点。
- O(log N + M) 的范围查询:找到区间起点,向后遍历直到终点。
为什么用跳表而非平衡树?
- 跳表实现简单,支持高效区间遍历。
- 并发扩展时,跳表的分层结构更容易实现无锁或细粒度锁优化。
步骤3:分数更新流程
-
在哈希表中查找用户ID:
- 若不存在,在哈希表中插入(用户ID, 新分数),同时在跳表中插入节点(新分数, 用户ID)。
- 若存在旧分数,比较新旧分数:
- 若新分数 ≤ 旧分数,忽略(分数不降)。
- 否则,从跳表中删除(旧分数, 用户ID),更新哈希表分数,并向跳表插入(新分数, 用户ID)。
-
时间复杂度:哈希表 O(1),跳表删除和插入 O(log N),整体 O(log N)。
步骤4:Top K 查询实现
- 从跳表的最高层头节点开始,向右遍历到第 K 个节点(或链表尾部)。
- 由于跳表按分数降序排列,前 K 个节点即为 Top K。
- 时间复杂度:O(K),因为跳表有序,无需排序。
步骤5:分段范围查询实现
- 在跳表中定位分数区间起点:
- 从高层向低层搜索,找到最后一个分数 ≥ 区间起点的节点。
- 从此节点开始,在底层链表向右遍历,直到分数 < 区间终点,收集所有节点。
- 返回用户列表和计数。
- 时间复杂度:O(log N + M),M 为区间内用户数。
步骤6:分布式扩展设计
为了支持海量数据,将用户按用户ID分片到多个节点(例如用一致性哈希分配):
- 分片规则:每个节点负责一部分用户ID的哈希表和跳表。
- 分数更新:根据用户ID路由到对应节点,节点内按上述流程更新。
- Top K 查询(全局):
- 每个节点本地取 Top K(因为全局最高分一定在各节点本地 Top K 中)。
- 聚合所有节点的 Top K 到协调节点,再合并排序取全局 Top K。
- 范围查询(全局):
- 向所有节点发送查询,各节点返回本地结果,协调节点汇总。
优化:
- 为加速全局 Top K,可在协调节点维护一个全局 Top K 的小顶堆,当节点分数更新时,若新分数可能影响全局 Top K,则向协调节点推送更新。
- 范围查询时,若区间较广,可并行查询各节点。
步骤7:一致性处理
分数“只增不减”需保证:
- 更新操作在单个节点内原子性(锁或 CAS)。
- 分布式下,若用户因迁移导致分片变化,需保证迁移过程中分数不丢失(例如先阻塞更新,迁移完成后解除)。
步骤8:复杂度总结
- 单节点:
- 更新:O(log N)
- Top K:O(K)
- 范围查询:O(log N + M)
- 分布式:
- 更新:O(log N) + 网络开销
- 全局 Top K:O(S * K) 合并(S 为分片数)
- 全局范围查询:O(S * (log N + M)) 并行合并
步骤9:扩展优化思路
- 冷热数据分离:长期不活跃用户归档,减少跳表大小。
- 缓存全局 Top K:协调节点缓存结果,定期或事件驱动更新。
- 跳表分层存储:高层索引可常驻内存,底层链表可存储在磁盘或 SSD(用 B+树变体)。
这个设计通过哈希表实现快速点查询,跳表实现高效范围操作,并结合分布式分片满足扩展性,适用于大规模实时排行榜场景。