如何设计高并发场景下的实时排行榜系统

核心思路:异步解耦+内存加速+增量推送

一、系统需求与核心目标

1. 核心需求

近似实时统计:数据满足最终一致性,无需强一致性

Top N查询:前端需快速获取前N名(如Top 100)

通用性设计:支持多业务类型(点赞/积分/评论等)

高并发支持:应对流量高峰和用户量增长

2. 非功能性要求

低延迟查询:减少数据库计算压力

幂等性保障:避免重复操作导致数据错误

可扩展性:支持动态扩容和任务隔离

二、数据库表设计

1. 历史记录表(操作流水)

字段设计

rank_type:排行榜类型(如点赞/评论/积分)

object_id:实体ID(用户/文章/游戏角色等)

count:操作数值(支持正负值)

create_time:操作时间

功能:记录原始操作流水,用于数据溯源和批量处理

2. 结果表(排行榜快照)

字段设计

object_id:实体ID

rank_type:排行榜类型

total_count:累计分数(如总点赞数)

create_time:更新时间

索引优化(rank_type, total_count)组合索引提升排序效率

三、架构演进与优化策略

1. 初期方案(同步调用)

流程:业务系统直接同步调用排行榜服务写入DB

问题

• 强耦合导致接口延迟高

• 数据库读写压力大,无法应对高并发

2. 引入消息队列(解耦与削峰)

技术选型:RocketMQ/Kafka

优化点

• 业务系统异步发送MQ消息,降低耦合

• 批量消费消息减少DB IO次数

• 按rank_type分区保证顺序性

幂等处理:通过唯一键(如object_id+create_time)避免重复消费

3. 引入Redis(实时排序加速)

技术选型:Sorted Set(ZSET)

实现方式

• Key结构:rank:{rank_type}(如rank:comments

• 操作命令:ZINCRBY更新分数,ZREVRANGE查询Top N

优势

• 内存排序实现毫秒级响应

• 支持动态分数更新

风险控制

• 避免大Key问题(分片或定期清理过期数据)

四、高可用与扩展性设计

1. 消费任务隔离

动态配置:按rank_type分配独立Topic和消费者组

物理隔离:不同业务类型独立部署消费任务

2. 高可用方案

HA机制:通过ZooKeeper/etcd实现消费任务主备切换

进度同步:记录消费位移(Offset),故障恢复后接续消费

五、实时推送优化

1. WebSocket集成

实时推送:服务端主动推送排行榜变化至客户端

推送触发条件:仅当Top N名次变化时触发

2. 变化检测策略

方案一:计算Top N数据的MD5摘要,对比变化后推送

方案二:逐条对比前N名数据,仅推送变化部分

增量推送:仅发送发生名次变动的实体(如最后一名替换)

六、性能优化补充

1. 数据存储优化

冷热分离:历史数据归档,仅保留活跃周期数据(如最近7天)

读写分离:主库处理写操作,从库分担读压力

2. Redis扩展方案

分片存储:按rank_type哈希分片,分散大Key压力

过期策略:为临时榜单设置TTL自动清理

七、关键注意事项

  1. 幂等性贯穿全流程:MQ消费、DB写入、Redis更新均需幂等设计
  2. 监控与告警: • 监控MQ堆积、Redis内存使用、DB慢查询 • 设置阈值触发扩容或降级
  3. 动态配置能力:支持运行时调整排行榜周期、Top N数量等参数
全部评论
用treemap+map可以实现java的zset,而且没有大key风险
2 回复 分享
发布于 04-07 01:33 上海
mark
点赞 回复 分享
发布于 05-18 10:49 广东
mark
点赞 回复 分享
发布于 05-02 16:33 上海
这是gpt生成的吗,我感觉有点过于复杂了
点赞 回复 分享
发布于 04-23 18:30 上海
mark
点赞 回复 分享
发布于 04-06 13:53 浙江

相关推荐

查看9道真题和解析 简历中的项目经历要怎么写
点赞 评论 收藏
分享
头像
05-09 16:22
已编辑
华南师范大学 Java
  一面四小时后通知次日二面——————————🧠 个人背景与项目经历1.XX系统是你们这边的项目吗?你一直在做这个项目吗?2.做过一个XX项目是吧?是学习项目还是公司项目?3.项目中你主要负责了什么?4.你参与的项目经验多吗?5.除了XX和XX系统,有没有别的项目可以讲讲?💻 技术能力 - 后端开发6.数据库与安全7.你们系统是怎么存储用户密码的?8.单纯用 MD5 会有撞库风险,如何防御?9.接口调用怎么验证调用方身份?10.使用 MD5 校验上传文件的目的是什么?☕Java & Spring11.Spring Boot 用了哪些 starter?各自的作用是什么?12.如果第三方 starter 功能不够怎么办?13.Spring Boot 中有没有用到 AOP?14.可以用来扩展 starter 的方式有哪些?15.Spring 全家桶覆盖的范围够用吗?多线程与线程安全16.ConcurrentHashMap 为什么线程安全?17.JDK1.8 之前和之后的实现有何区别?18.size() 方法是怎么统计的?是否加锁?🔐 安全性与权限控制19.上传文件前需要做哪些安全校验?接口安全20.接口层面做了哪些安全处理?21.JWT 是怎么生成的?22.JWT 是用哪个库实现的?签名算法是什么?23.Token 刷新的触发机制是什么?24.项目中有没有做 token 自动续期?幂等性25.接口幂等性有哪些实现方式?⚙️ 系统架构与中间件26.Redis 与缓存机制27.什么是缓存穿透?怎么解决?28.什么是缓存击穿?怎么解决?29.什么是缓存雪崩?怎么解决?30.热 key 会带来什么问题?如何应对?MQ & 延迟任务31.用 MQ 实现了什么业务?32.如何通过 MQ 做延迟队列?解决了什么问题?🧱 设计模式33.工厂模式和抽象工厂模式的区别是什么?34.代理模式和装饰器模式有什么不同?🧠 Java 基础知识35.Java 能否继承多个类?36.接口中能定义实现方法吗?JDK8 之后呢?37.接口中 default 方法你了解吗?🧪 Linux 运维基础38.在 Linux 下怎么查看远程端口是否可达?39.除了 telnet 还有什么命令可以测试端口?(比如 nc)
点赞 评论 收藏
分享
评论
8
67
分享

创作者周榜

更多
牛客网
牛客企业服务