基于Node.JS和MongoDB实现限时排行榜的方案探讨
限时游戏积分排行榜优化方案
1. 预聚合存储(首推)
- 拆分时间维度存储积分:给用户文档新增
dailyOranges、weeklyOranges字段,或者单独建一张积分聚合表,专门记录每个用户每日、每周的累计积分。 - 实时同步更新:用户拿到积分时,除了更新全时段的
totalOranges,同时根据当前时间戳,把对应数值加到当天的dailyOranges或本周的weeklyOranges里。 - 查询效率:做24小时/7天排行榜时,直接读这些聚合字段排序就行,不用再遍历全量积分流水,读取量直接从10k+用户的全量数据降到仅读取聚合字段,性能拉满。
2. 时间范围索引优化
- 如果不想改原有存储结构,给积分记录里的
epoch time字段加个范围索引。 - 查询时直接用时间范围过滤(比如
epoch time > 当前时间戳 - 86400),只拉取近24小时的积分记录再算总和。 - 注意:就算有索引,10k+用户的情况下每次查询还是得遍历匹配的记录,适合积分流水不多的场景,性能不如预聚合。
3. 离线计算+缓存
- 搞个定时任务(比如每小时跑一次),离线算出所有用户的24小时/7天积分总和,把结果存到Redis的Sorted Set这类缓存里。
- 查排行榜直接读缓存,缓存过期或者需要更新时再触发离线计算。如果要准实时,就缩短定时任务间隔,或者用户拿积分时同步更新缓存里的对应时段分数。
- 优势:查询速度最快,适合对实时性要求不是特别高的场景。
4. 按时间分片存储
- 把积分流水按时间分片,比如每天一个分片表/集合。
- 查近24小时积分只需要操作当天的分片,查7天就操作最近7个分片,大幅减少数据扫描的范围。
- 适合积分流水特别大的场景,搭配预聚合用效果更好。
内容的提问来源于stack exchange,提问作者Bhavesh Shaha
相关产品推荐
相关产品推荐

