2026/2/24 17:43:02
网站建设
项目流程
建设网站的风格,ui网页设计尺寸,上海好公司排名前十,wordpress登录修改密码前言大家好分享一道网上很火的腾讯面试题:亿级用户排行榜怎么设计呢#xff1f;换种说法#xff0c;王者荣耀亿级排行榜#xff0c;如何设计#xff1f;本文田螺哥从面试的角度#xff0c;跟大家一起探讨一下#xff0c;如何回答更好呢#xff1f;数据库的order by为什么…前言大家好分享一道网上很火的腾讯面试题:亿级用户排行榜怎么设计呢换种说法王者荣耀亿级排行榜如何设计本文田螺哥从面试的角度跟大家一起探讨一下如何回答更好呢数据库的order by为什么不行为什么Redis是排行榜的“扛把子”Redis扛亿级数据可能存在哪些问题以及对应解决方案实现方案分治巨人的肩膀前人踩过的坑1. 数据库的order by很多小伙伴一提到排行榜就想到数据库的order by。比如微信运动的步数排行vbnet体验AI代码助手代码解读复制代码select * from user_info order by step desc这个实现没有问题的如果表的数据量少的话反而推荐这样实现。如果数据量多呢。则存在问题尤其还涉及亿级的数据量时~在亿级用户高并发实时更新的场景下会彻底崩盘。 原因一句话磁盘扛不住排序算不动并发撑不起。2.为什么Redis是排行榜的扛把子当数据量较大且需要实时更新并频繁查询时使用 Redis 的zset有序集合更为适合。zset是Redis提供的一种数据结构它类似于集合set但每个成员都关联着一个分数scoreRedis 使用这个分数来对集合中的成员进行排序。不仅仅是redis的zset支持排序API简单易用还因为redis的排序快、可扩展性强、能轻松应对高并发。2.1 redis排序快Redis 的数据全放内存避免磁盘读写核心操作秒回更新分数ZADD→ 快如闪电查排名ZREVRANK→ 毫秒响应查Top 100ZREVRANGE→ 瞬间出结果以下为 Redis vs MySQL 性能对比亿级数据操作Redis (Sorted Set)MySQL (ORDER BY)更新单个用户分数0.1ms5~50ms索引更新代价高查询用户排名0.2ms100ms~5s依赖索引和缓存获取Top 1001ms1s~10s内存排序或临时文件高并发支撑能力10万/秒1000/秒需分库分表2.2 可扩展性强分片存储轻松应对亿级数据。Redis通过分片存储将数据拆分到多个实例如同把1亿用户分配到10个小数据库每个只需处理1000万数据轻松实现1️⃣ 线性扩展加机器就能提升容量和性能2️⃣ 压力分散读写请求分摊到不同分片避免单点瓶颈3️⃣ 独立扩容热点分片可单独升级配置不干扰其他节点类比理解把一仓库货物数据分装到10辆卡车分片每辆车只运1/10的货装卸速度自然快10倍2.3 轻松应对高并发Redis用内存操作单线程IO多路复用三把利剑轻松切开高并发大山1️⃣ 内存闪电读写数据全放内存比磁盘快10万倍2️⃣ 单线程无锁避免多线程切换损耗原子操作不怕并发冲突3️⃣ IO多路复用一个线程监听万个连接像银行超级柜员同时处理多窗口业务田螺哥打个比喻吧Redis就像一个超高效快餐窗口只卖预制菜内存数据→ 出餐快一个收银员专注打单单线程→ 不手忙脚乱智能叫号器管理排队IO多路复用→ 千人排队也能快速响应据有关测试证明单机Redis可扛10万 QPS分片集群轻松突破百万级并发。3.Redis扛亿级数据可能存在哪些问题以及对应解决方案3.1 热Key问题比如“全服TOP100”榜单容易造就热点key问题。全服玩家频繁查询 ZREVRANGE leaderboard 0 99获取Top 100导致所有请求集中访问 同一个Keyleaderboard。容易导致单分片CPU和带宽被打满假设数据分片不均匀。极端情况下Redis实例崩溃全服排行榜瘫痪可以通过这些方式解决1. 多级缓存Redis jvm本地缓存请求优先读本地内存缓存缓存未命中时读Redis集群Redis集群内部缓存Top 100设置更短TTL读写分离 从库负载均衡主库处理写请求更新分数。多个从库轮询处理读请求查Top 100分片Key设计操作将排行榜按分数区间拆分成多个Key例如leaderboard:top1前100名leaderboard:top2101~1000名leaderboard:rest其他用户查询逻辑查Top 100时只需访问 leaderboard:top1。3.2 内存爆炸存储1亿用户若每个键占32字节如 user:123仅键就需约3.2GB加上分数和指针内存压力巨大。优化方案缩短键名将 user:123 转换为整数如123利用 Redis 的 int 编码优化内存。分片存储按用户ID哈希分片到多个 Redis 实例分散压力。3.3 数据持久化风险Redis 宕机可能导致最新数据丢失即使开启AOF默认每秒同步一次。容灾方案异步双写更新分数时同步写入 Kafka由消费者异步落库 MySQL用于故障恢复。混合持久化开启 RDB AOF平衡恢复速度与数据完整性。4. 实现方案分治比如我们要查询王者荣耀巅峰赛的前一百积分的玩家。其实就是一个TOP N问题我们可以按照这种思路按区间拆分动态路由聚合查询4.1. 按区间拆分把排行榜切成小块蛋糕**怎么拆高分玩家放「金盘子」2500分以上 →rank:2500_2600中分玩家放「银盘子」2400~2500分 →rank:2400_2500低分玩家丢「大锅」0~2400分 →rank:0_2400为什么快查Top 100只需翻「金盘子」不用搅动整个大锅盘子越小 → 翻找速度越快4.2 动态路由玩家换区自动导航怎么动玩家积分变化时自动检测该去哪yaml体验AI代码助手代码解读复制代码# 伪代码2503分该放哪个区间 if 2500 new_score 2600: 扔进 rank:2500_2600 elif 2400 new_score 2500: 扔进 rank:2400_25004.3 聚合查询拼图式合并结果怎么拼从高到低翻盘子先查「金盘子」→ 拿到前50名不够100再查「银盘子」→ 补50名全局排序把两个盘子的100人按分数重新排座次5. 巨人的肩膀前人踩过的坑慎用ZREVRANGE类全量操作直接使用ZREVRANGE获取Top N时若数据量过大如1亿用户会触发O(N)复杂度遍历导致Redis线程阻塞警惕黑马用户冲击分片策略突然出现的高分用户如积分暴涨至前0.1%可能打乱原有分片规则导致数据集中在某个分片引发热点。内存爆炸与性能抖动亿级用户存储占用内存超限且RDB/AOF持久化时fork子进程引发内存翻倍。数据迁移阻塞服务用户积分跨分片迁移时若未原子操作可能导致数据丢失或重复。