news 2026/5/13 1:26:18

排行榜设计实战:Redis ZSet 遇到“千万级玩家”积分实时更新,该如何优化?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
排行榜设计实战:Redis ZSet 遇到“千万级玩家”积分实时更新,该如何优化?

🎮 前言:当 1000 万玩家同时冲榜

场景还原:
某款 MOBA 手游开启“全服天梯赛”,预计活跃玩家 1000 万。
策划要求:“积分变化要实时反映在排行榜上,我就要看到那个排名跳动的爽感!”

作为后端开发,你自信地掏出了 Redis 的ZSet

ZADD rank_global1050"Player_A"

结果活动开启第 10 分钟,Redis CPU 飙升 100%,网络带宽被打满,客户端请求全部超时。运维查监控发现,rank_global这个 Key 的大小已经超过了 500MB。

恭喜你,制造了一个标准的“BigKey”事故。

在千万级数据下,单纯依赖一个 ZSet 是死路一条。今天,我们就来聊聊如何设计一个打不死的实时排行榜系统。


💀 瓶颈分析:ZSet 为什么会挂?

Redis 的ZSet底层使用的是跳表 (SkipList)哈希表
虽然它的增删查复杂度是O(log⁡N)O(\log N)O(logN),但在千万级数据下存在两大硬伤:

  1. BigKey 问题:一个 Key 包含 1000 万个元素,进行ZRANGEZREVRANGE时,如果页大小设置不当,会造成大量的网络 IO。更有甚者,如果这个 Key 需要迁移(集群 Rebalance),会阻塞 Redis 很久。
  2. 写并发瓶颈:Redis 是单线程写。如果全服玩家同时拿分,TPS 达到 10 万+,单机 Redis 根本扛不住高频的ZADD更新。

⚔️ 优化方案一:分治法 —— ZSet 分桶 (Sharding)

既然一个 ZSet 装不下,那我们就把它拆成 128 个,甚至 1024 个。

核心思路:

  1. 入榜:根据UserID % N将玩家分散到rank_0rank_127这 128 个小 ZSet 中。
  2. 查询 Top N:这是难点。如果我要查全服 Top 10,我必须从这 128 个 ZSet 中,分别取出各自的 Top 10,然后在应用内存中进行“归并排序”,选出最终的 Top 10。

架构图解:

Redis 集群
Hash 取模
UserID % 3 == 0
UserID % 3 == 1
UserID % 3 == 2
并行读取
并行读取
并行读取
返回各自 Top 10
返回各自 Top 10
返回各自 Top 10
内存归并排序
Key: rank_part_0
应用层分发
Key: rank_part_1
Key: rank_part_2
海量玩家写请求
查询全服 Top 10
应用层
最终 Top 10
  • 优点:彻底解决了 BigKey 问题,写入性能线性扩展。
  • 缺点:查询 Top N 变复杂了。但通常排行榜只看前 100 名,归并 128 * 100 个数据的开销完全可以接受。

🚀 优化方案二:降维打击 —— 头部实时,尾部离线

策划说要“实时”,但真的所有 1000 万人都关心自己是第 9,999,998 名吗?
显然不是。只有头部玩家(前 1000 名)在乎毫秒级排名,普通玩家只要知道自己大概在前 50% 就行了。

设计策略:

  1. Top K 实时榜:Redis 中只保留积分最高的Top 5000用户。
    • 当玩家积分变化时,如果积分 > 第 5000 名的积分,则ZADD进 Redis。
    • 如果 Redis 元素超过 5000,则定期移除末尾用户。
  2. 全量离线榜:所有用户的完整积分数据存入 MySQL 或 HBase。
    • 普通用户的排名,通过定时任务(每 5 分钟)或者查询数据库统计得出。
    • 或者直接显示“未上榜”。

代码逻辑示例 (Lua 脚本保障原子性):

-- ARGV[1]: 玩家 ID-- ARGV[2]: 新积分-- ARGV[3]: 排行榜容量 (如 5000)localkey=KEYS[1]localscore=tonumber(ARGV[2])-- 1. 更新分数redis.call('ZADD',key,score,ARGV[1])-- 2. 检查是否超出容量localcount=redis.call('ZCARD',key)ifcount>tonumber(ARGV[3])then-- 移除分数最低的那个人 (排名在 0 到 count-limit 之间的人)redis.call('ZREMRANGEBYRANK',key,0,count-tonumber(ARGV[3])-1)end

🛡️ 优化方案三:写缓冲 (Write-Back)

在直播间刷礼物场景下,土豪手速极快,一秒钟送出 100 个“666”。
如果每次送礼都请求一次 Redis,网络开销太大。

策略:本地聚合

  1. 在应用服务器(Java/Go)内存中维护一个ConcurrentHashMap<UserId, Score>
  2. 收到加分请求时,只更新内存。
  3. 每隔1 秒,或者累积满 100 个操作,批量将变化刷入 Redis (ZINCRBY)。

这样可以将 Redis 的写 QPS 降低一个数量级(10w -> 几千)。虽然有 1 秒的数据延迟,但在用户体验和系统稳定性之间,这是极佳的权衡。


📊 总结

设计千万级排行榜,不要试图用一个 ZSet 解决所有问题。

  1. 要分片:避免 BigKey 阻塞 Redis。
  2. 要截断:只存头部数据,尾部数据走数据库。
  3. 要缓冲:合并高频写入,保护 Redis 带宽。

没有完美的技术,只有最适合业务场景的架构。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 23:27:23

图像搜索革命:Search By Image全功能深度解析

图像搜索革命&#xff1a;Search By Image全功能深度解析 【免费下载链接】Search-By-Image Search By Image | 以图搜图 项目地址: https://gitcode.com/gh_mirrors/sea/Search-By-Image 还在为找不到图片来源而烦恼吗&#xff1f;一张神秘的图片背后可能隐藏着丰富的信…

作者头像 李华
网站建设 2026/5/12 20:05:15

Maxun元数据过滤终极指南:5步实现精准网页数据提取

Maxun元数据过滤终极指南&#xff1a;5步实现精准网页数据提取 【免费下载链接】maxun &#x1f525;Open Source No Code Web Data Extraction Platform. Turn Websites To APIs & Spreadsheets With No-Code Robots In Minutes&#x1f525; 项目地址: https://gitcode…

作者头像 李华
网站建设 2026/5/11 0:14:38

Higress v2迁移实战:从v1到v2的零中断升级手册

还在为网关升级可能导致的业务中断而担忧吗&#xff1f;&#x1f680; Higress v2版本带来了30多项重大改进&#xff0c;通过本文的四阶段渐进式迁移方案&#xff0c;你将实现平滑升级&#xff0c;全程保障业务连续性。作为下一代云原生网关&#xff0c;Higress v2在AI能力集成…

作者头像 李华
网站建设 2026/5/11 0:14:05

分组查询注意力(GQA):Transformer推理优化的工程实践与性能突破

分组查询注意力(GQA)&#xff1a;Transformer推理优化的工程实践与性能突破 【免费下载链接】xformers Hackable and optimized Transformers building blocks, supporting a composable construction. 项目地址: https://gitcode.com/gh_mirrors/xf/xformers 在大型语言…

作者头像 李华
网站建设 2026/5/10 20:25:55

vue基于Spring Boot的网上流浪狗救助捐赠平台应用和研究_ln50093y

目录具体实现截图项目介绍论文大纲核心代码部分展示项目运行指导结论源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作具体实现截图 本系统&#xff08;程序源码数据库调试部署讲解&#xff09;同时还支持java、ThinkPHP、Node.js、Spring B…

作者头像 李华
网站建设 2026/5/10 20:25:08

wgpu渲染管线:跨平台GPU编程的现代化解决方案

wgpu渲染管线&#xff1a;跨平台GPU编程的现代化解决方案 【免费下载链接】wgpu Cross-platform, safe, pure-rust graphics api. 项目地址: https://gitcode.com/GitHub_Trending/wg/wgpu 你是否曾经为不同平台的图形API差异而头疼&#xff1f;是否在WebGL的性能瓶颈和…

作者头像 李华