设计一个基于哈希的分布式实时游戏排行榜系统(支持分数更新和Top K查询)
字数 987 2025-11-28 05:56:32
设计一个基于哈希的分布式实时游戏排行榜系统(支持分数更新和Top K查询)
题目描述
设计一个分布式实时游戏排行榜系统,支持以下操作:
add_score(user_id, score):为指定用户添加分数(可多次调用,分数累加)top_k(k):返回当前排名前K的用户ID及其总分(按分数降序,分数相同时按用户ID升序)- 系统需支持高并发场景,并保证数据一致性。
解题过程
-
问题分析
- 需要维护每个用户的总分(多次
add_score累加)。 - 需高效返回Top K结果,且支持动态分数更新。
- 分布式环境下需处理并发冲突和数据分片。
- 需要维护每个用户的总分(多次
-
核心数据结构设计
- 用户分数存储:使用哈希表(如Redis的Hash结构)记录每个用户的累计分数,键为
user_id,值为总分。- 例:
user_scores = {"user1": 150, "user2": 200}
- 例:
- 排行榜维护:使用有序集合(如Redis的ZSet)按分数排序,分数相同时按用户ID排序(可通过将分数与ID组合为排序键实现)。
- 例:ZSet中存储的分数值为
(实际分数 * 10^6 + 用户ID数字后缀),确保分数相同时按ID排序。
- 例:ZSet中存储的分数值为
- 用户分数存储:使用哈希表(如Redis的Hash结构)记录每个用户的累计分数,键为
-
分数更新策略
- 步骤:
- 接收
add_score(user_id, score)请求。 - 原子性更新哈希表中的用户总分(例如使用Redis的
HINCRBY)。 - 同步更新有序集合:先删除旧分数(若存在),再插入新分数(组合分数键)。
- 接收
- 并发控制:通过分布式锁或原子操作(如Redis的Lua脚本)保证哈希表和有序集合的更新一致性。
- 步骤:
-
Top K查询实现
- 直接查询有序集合的倒序前K个元素(如Redis的
ZREVRANGE命令)。 - 解析组合分数键,返回原始用户ID和分数。
- 直接查询有序集合的倒序前K个元素(如Redis的
-
分布式扩展
- 数据分片:按用户ID分片存储用户分数哈希表(如根据ID哈希值分到不同节点)。
- 全局排行榜:通过定期聚合各分片的有序集合(如使用归并排序)生成全局Top K,或使用分布式排序算法(如TeraSort)。
-
优化措施
- 异步更新:非实时场景下,可异步批量更新有序集合,减少写压力。
- 缓存Top K结果:为高频查询的K值缓存排行榜结果,设置短过期时间。
总结
通过哈希表维护用户分数,结合有序集合实现高效排序,配合分布式锁和分片策略,可构建支持高并发实时更新的游戏排行榜系统。