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

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

一、系统需求与核心目标

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风险
1 回复 分享
发布于 04-07 01:33 上海
mark
点赞 回复 分享
发布于 04-06 13:53 浙江

相关推荐

评论
4
28
分享

创作者周榜

更多
牛客网
牛客企业服务