Apollo 技术文档Apollo 技术文档
指南
  • 架构概述
  • BigWorld 架构深度解析
  • BigWorld 进程架构与玩家生命周期
  • AOI九宫格系统详解
  • AOI广播与消息去重
  • Base 模块
  • Core 模块
  • Runtime 模块
  • Data 模块
  • Network 模块
  • /modules/actor.html
  • Game 模块
  • BigWorld 模块
服务器应用
API 参考
QA
GitHub
指南
  • 架构概述
  • BigWorld 架构深度解析
  • BigWorld 进程架构与玩家生命周期
  • AOI九宫格系统详解
  • AOI广播与消息去重
  • Base 模块
  • Core 模块
  • Runtime 模块
  • Data 模块
  • Network 模块
  • /modules/actor.html
  • Game 模块
  • BigWorld 模块
服务器应用
API 参考
QA
GitHub
  • MMORPG 架构 QA

Q30: 如何设计排行榜系统?

核心结论

排行榜系统真正要解决的,不是“把人按分数排一下”,而是同时处理好:

  • 排名更新成本
  • 查询热点
  • 周期结算
  • 跨服聚合
  • 奖励发放和审计

大多数项目里,排行榜不是单一表结构问题,而是“实时视图加结算流程”问题。

一、先明确排行榜类型

不同排行榜,设计重点完全不同。

常见类型包括:

  • 实时成长榜,例如等级、战力
  • 竞技榜,例如积分、段位
  • 周期活动榜,例如周榜、赛季榜
  • 公会或跨服榜

需要先分清:

  • 是实时展示为主,还是结算奖励为主
  • 是单服,还是跨服
  • 是只查 Top N,还是大量查个人名次

二、排行榜最核心的两类访问

通常离不开两种:

1. Top N 查询

例如前 10、前 100、前 1000。

2. 个人名次查询

例如“我现在第几名”“我附近的人是谁”。

这两类查询如果没有提前按访问模式设计,后期很容易变慢。

三、为什么排行榜不适合每次都扫数据库

原因很直接:

  • 查询频繁
  • 排序成本高
  • 热点集中

所以大多数实时排行榜都会放到更适合排序和快速查询的结构里,例如:

  • Redis 有序集合
  • 内存排序结构
  • 专门的聚合服务

数据库更适合承接持久化快照和结算结果,而不是直接扛所有实时排名查询。

四、实时榜和结算榜要分开看

1. 实时榜

更关注:

  • 快速更新分数
  • 快速查 Top N
  • 快速查个人排名

2. 结算榜

更关注:

  • 截止时间点的最终结果
  • 奖励发放顺序
  • 审计与复核

很多事故都来自把“实时变化中的榜单”直接当作“最终结算依据”。

更稳妥的做法通常是:

  • 结算时生成冻结快照
  • 奖励按冻结结果发放

五、跨服排行榜为什么更难

因为它不仅是排序问题,还涉及:

  • 多服数据汇总
  • 更新频率控制
  • 口径一致
  • 延迟可接受范围

很多跨服榜不适合每次变化都全量实时同步,常见做法是:

  • 分服先维护本地榜
  • 聚合层按周期或流式合并
  • 客户端接受短时间延迟

六、奖励发放必须和排名解耦

排行榜展示错一两秒,通常只是体验问题;奖励发错,就是严重事故。

所以结算链路通常需要:

  • 冻结榜单
  • 幂等发奖
  • 发奖流水
  • 可补偿

不要把“客户端看到的最新榜”直接作为发奖依据。

七、工程上常见的稳妥结构

很多项目最终会是:

  • Redis 或内存结构承接实时排名
  • 数据库保存角色基础数据和结算快照
  • 单独的结算任务负责赛季或活动发奖
  • 高价值奖励链路具备幂等和审计

这样职责更清晰。

八、常见误区

1. 排行榜就是 Redis ZSet

ZSet 很常用,但它只解决了排序和查询的一部分问题,不自动解决结算、发奖、跨服聚合。

2. 排名必须绝对实时

很多场景并不需要。为了几秒内的完全实时付出高昂系统成本,往往不划算。

3. 排行榜展示和奖励发放可以共用同一条链路

风险很大。展示允许小延迟,奖励不能出错。

参考资料

  • Redis Sorted Set 官方资料
  • 各类在线游戏赛季榜与活动榜结算实践资料
在 GitHub 上编辑此页
最后更新: 3/20/26, 6:06 AM
贡献者: cuihairu