ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

腾讯二面真题:王者荣耀亿级排行榜如何架构设计?

腾讯二面真题:王者荣耀亿级排行榜如何架构设计? 我们是由枫哥组建的IT技术团队成立于2017年致力于帮助IT从业者提供实力成功入职理想企业我们提供一对一学习辅导由知名大厂导师指导分享Java技术、参与项目实战等服务并为学员定制职业规划全面提升竞争力过去8年我们已成功帮助数千名求职者拿到满意的OfferIT枫斗者、IT枫斗者-Java面试突击。腾讯二面真题王者荣耀亿级排行榜如何架构设计王者荣耀、微信步数、抖音榜单这类亿级用户、高并发实时更新、高频查询的排行榜场景是大厂后端面试的经典高频题。面试官核心考察三点为什么传统数据库ORDER BY扛不住亿级排行为什么 Redis ZSet 是排行榜最优解纯 ZSet 存在哪些亿级流量隐患如何落地优化本文从面试视角完整拆解一套可落地、无漏洞、高可用的亿级排行榜架构方案。一、为什么数据库 ORDER BY 不能做亿级排行榜很多新手第一反应排行榜直接用 SQL 排序不就行了SELECT*FROMuser_infoORDERBYscoreDESCLIMIT100;小数据量场景完全可用、简单省心、无需额外组件。亿级高并发场景直接崩盘核心问题一句话总结磁盘扛不住、排序算不动、并发撑不起。核心痛点磁盘IO瓶颈MySQL 数据落磁盘每次排序需要大量磁盘读写响应耗时数百毫秒甚至秒级。排序计算昂贵实时排序是 O(NlogN) 计算复杂度亿级数据无法实时计算。完全无法抗并发榜单是高频查询接口大量用户同时刷新榜单数据库 CPU、IO 会直接打满引发雪崩。结论数据库只适合离线统计、低频榜单绝对不适合实时亿级排行榜。二、为什么 Redis 是排行榜“扛把子”工业级实时排行榜清一色基于Redis ZSet有序集合实现没有之一。ZSet 核心特性每个成员绑定一个 score分数Redis 自动根据分数排序天然适配排行榜场景。相比数据库Redis 三大碾压优势速度快、可扩展、高并发。2.1 全内存操作毫秒级响应所有数据常驻内存规避磁盘IO瓶颈核心操作都是毫秒级更新玩家分数ZADD极速写入查询个人排名ZREVRANK秒查查询Top榜单ZREVRANGE瞬间返回结果内存速度比磁盘快10万倍是实时榜单的核心基础。2.2 集群分片轻松承载亿级数据单实例内存、性能有限Redis 支持分片集群水平扩容。核心逻辑将亿级用户数据拆分到多个独立 Redis 分片。类比1亿用户数据拆分10个分片每个分片仅承载1000万数据压力直接均分。分片三大优势线性扩容加机器即可提升容量、并发能力压力分散读写请求分摊彻底解决单点瓶颈灵活运维热点分片单独升级配置不影响全局服务2.3 架构优势支撑十万级QPSRedis 高并发三大杀手锏内存读写 单线程无锁 IO多路复用内存预制数据无磁盘等待出结果极快单线程执行命令无线程竞争、无锁开销、无上下文切换损耗epoll IO多路复用单线程监听上万连接支撑海量并发请求单机 Redis 可稳定支撑10万 QPS集群分片后可轻松突破百万级并发完全覆盖王者荣耀亿级用户并发场景。三、纯Redis ZSet 亿级场景的致命隐患 解决方案ZSet 不是万能的直接单Key存储全服亿级榜单会出现热Key、内存爆炸、数据丢失三大致命问题必须针对性优化。3.1 热Key问题最核心风险问题现象全服榜单查询高度集中所有用户请求都访问同一个 Key如 leaderboard:all导致单分片 CPU、带宽打满极端情况引发 Redis 宕机、榜单全服瘫痪。解决方案三套组合拳① 多级缓存JVM本地缓存 Redis缓存榜单Top100高频数据优先读取服务端本地缓存本地缓存未命中再请求 Redis 集群Redis 内部短TTL缓存热点榜单数据减少重复计算② 读写分离 从库负载均衡主库专注处理写请求玩家积分更新多个从库轮询承接读请求榜单查询彻底分摊热点压力③ 区间分片Key设计根治热Key将单一全局榜单拆分为多区间独立Keyleaderboard:top1前100名高分玩家leaderboard:top2101~1000名leaderboard:rest普通低分玩家查询Top100仅需访问高分分片无需遍历全量数据彻底解决全局热Key。3.2 内存爆炸问题问题现象亿级用户存储开销极大单Key存储所有用户键名、分数、指针叠加内存占用超限极易触发OOM。优化方案精简键名舍弃冗长键名直接使用用户ID数字作为成员利用Redis整型编码压缩内存用户ID哈希分片按用户ID哈希规则打散到不同Redis实例单实例存储量大幅降低冷数据淘汰长期不登录、无积分变动的玩家临时移出榜单增量更新恢复3.3 数据持久化 容灾风险问题现象Redis 内存数据易失单机宕机会丢失最新积分数据默认AOF每秒同步仍存在秒级数据丢失风险。容灾落地方案混合持久化RDBAOF兼顾快速恢复与数据完整性异步双写兜底积分更新同步写入Kafka消费者异步落地MySQL作为故障恢复唯一数据源定时全量兜底定时将榜单核心数据落地数据库防止长期数据偏差四、亿级榜单终极落地分治架构方案针对王者荣耀巅峰赛、全服排行榜这类极致场景行业通用最优解是区间分治 动态路由 聚合查询。4.1 按分数区间拆分切块存储将全服积分划分为多个梯度分片高分单独存储避免全量遍历高分段2500分以上 → rank:2500_2600核心Top榜单中分段2400~2500分 → rank:2400_2500低分段0~2400分 → rank:0_2400核心优势查询Top100仅需检索高分分片无需遍历亿级全量数据查询性能极致拉满。4.2 动态路由自动迁移分片玩家积分实时变动通过路由规则自动匹配对应分片伪代码逻辑// 积分变更后自动路由分片if(newScore2500newScore2600){zAdd(rank:2500_2600,userId,newScore);}elseif(newScore2400newScore2500){zAdd(rank:2400_2500,userId,newScore);}else{zAdd(rank:0_2400,userId,newScore);}积分跨越区间时自动删除旧分片数据、写入新分片保证榜单数据准确。4.3 聚合查询拼图式结果合并查询全服Top100时采用从高到低逐级聚合策略优先查询最高分段分片获取高分玩家数据数量不足Top100时向下一级分片补充数据内存中统一二次排序返回完整精准榜单既保证查询性能又保障全局榜单排序准确性。五、行业踩坑总结面试加分避坑点大厂实际落地中极易踩的4个坑面试主动提及直接加分5.1 禁止超大Key全量遍历ZREVRANGE 全量遍历复杂度为 O(N)亿级数据下会阻塞Redis主线程引发服务卡顿必须通过区间分片规避。5.2 警惕黑马用户打乱分片平衡部分玩家积分暴涨会导致高分分片数据突增、压力不均需要动态阈值分片 临时扩容机制。5.3 规避持久化内存抖动RDB/AOF 持久化fork子进程会临时翻倍占用内存亿级数据下极易触发OOM需配置内存上限、定时低峰期持久化。5.4 跨分片迁移保证原子性玩家积分跨区间迁移时先删旧数据、再写新数据需加分布式锁避免数据重复、丢失导致榜单错乱。六、面试满分总结话术面对王者荣耀亿级实时排行榜我会采用**「Redis ZSet 分治分片 多级缓存 容灾兜底」**的整套架构1.放弃数据库排序舍弃MySQL ORDER BY规避磁盘IO与海量排序的性能瓶颈2.ZSet核心承载依托Redis内存架构、单线程模型、IO多路复用支撑十万级高并发实时读写3.区间分治优化按积分梯度拆分多分片解决热Key、全量遍历卡顿问题4.多级缓存读写分离本地缓存兜底热点查询从库分担读压力提升并发上限5.多层容灾兜底RDBAOF混合持久化、Kafka异步落库MySQL保障数据不丢失、服务高可用。整套方案可完美支撑亿级用户、毫秒级更新、百万级并发的游戏全服榜单场景。⭐️推荐:Offer训练营介绍Java 面试 后端通用面试八股文Java后端企业级实战面试Java后端校招算法学习
返回列表