编程指南-学习建议编程指南-学习建议
首页
学习方向
技术学习
🚀 编程指南
首页
学习方向
技术学习
🚀 编程指南
  • 三、技术学习

    • 技术指南

      • 前端技术知识

        • 什么是前端?
      • 后端技术知识

        • 什么是缓存?
        • 什么是工作流技术?
        • 什么是反向压力?
        • 什么是热数据探测?
        • 数据库也能版本控制?
        • /tech-learning/guide/backend/how-search-engine-works.html
        • /tech-learning/guide/backend/learn-concurrency.html
        • /tech-learning/guide/backend/other-databases.html
      • 通用技术知识

        • 什么是前后端分离?
        • /tech-learning/guide/general/what-is-redirect.html
        • 什么是单例模式?
        • /tech-learning/guide/general/what-is-magic-value.html
        • 什么是负载均衡?
        • /tech-learning/guide/general/what-is-multi-env.html
        • /tech-learning/guide/general/what-is-magic-number.html
        • 什么是 Linux?
        • /tech-learning/guide/general/what-is-cloud-dev.html
    • 系统设计

      • 如何设计一个实时排行榜系统?
      • /tech-learning/system-design/elasticsearch-optimization.html
      • /tech-learning/system-design/file-upload.html
      • /tech-learning/system-design/log-system.html
      • /tech-learning/system-design/software-sword.html
      • 如何设计好 API 接口?
      • /tech-learning/system-design/sdk-development.html
      • /tech-learning/system-design/architecture-design.html
      • /tech-learning/system-design/release-stability.html
    • 开发经验

      • 解决 Bug 经验
      • 如何快速上手新项目?
      • /tech-learning/dev-experience/enterprise-software.html
      • /tech-learning/dev-experience/opensource-contribute.html
      • 什么是代码规范?为什么要遵循代码规范?
      • /tech-learning/dev-experience/company-standards.html
      • /tech-learning/dev-experience/code-reuse.html
      • /tech-learning/dev-experience/quick-website.html
      • /tech-learning/dev-experience/vscode-remote.html
      • /tech-learning/dev-experience/linux-vm-remote.html
      • /tech-learning/dev-experience/young-contributor.html
      • /tech-learning/dev-experience/no-force-shutdown.html
      • /tech-learning/dev-experience/no-hardcode.html
      • /tech-learning/dev-experience/backend-attention.html
      • 千万别直接敲代码!(写代码前要做的事)
      • /tech-learning/dev-experience/project-attention.html
      • /tech-learning/dev-experience/website-online.html
      • /tech-learning/dev-experience/tech-selection.html

如何设计一个实时排行榜系统?

排行榜是很常见的需求,今天聊聊怎么设计。

需求分析

典型的排行榜需求:

  • 用户有分数
  • 按分数排名
  • 能查询排名
  • 分数会实时变化

比如游戏积分榜、文章热度榜、销量排行榜。

方案一:数据库排序

最简单的方案,直接查数据库:

SELECT user_id, score 
FROM user_score 
ORDER BY score DESC 
LIMIT 100

优点:简单

缺点:数据量大的时候很慢,而且每次都要全表排序

适用场景:数据量小、访问量低

方案二:Redis ZSET

Redis的有序集合天生适合做排行榜。

# 设置分数
ZADD ranking 100 user1
ZADD ranking 200 user2
ZADD ranking 150 user3

# 获取排行榜(分数高的在前)
ZREVRANGE ranking 0 99 WITHSCORES

# 查询某用户排名
ZREVRANK ranking user1

# 更新分数
ZINCRBY ranking 10 user1

优点:

  • 性能好,O(logN)的时间复杂度
  • 支持实时更新
  • 原子操作,不用担心并发问题

缺点:

  • 数据量特别大时(亿级)内存压力大

适用场景:大部分排行榜需求

方案三:分段+汇总

数据量特别大时,可以分段存储:

  • 按分数段分成多个ZSET
  • 查询时合并结果

或者用定时任务批量计算排名,存到缓存里。

设计要点

1. 考虑数据量

数据量小用MySQL就行,数据量大用Redis。

2. 考虑更新频率

更新频繁用Redis,更新不频繁可以定时批量计算。

3. 考虑排名方式

只要Top N还是要查询任意用户的排名?要求不同,方案不同。

4. 考虑并发

分数更新可能并发,用Redis的原子操作可以避免问题。

一个实际例子

假设做一个游戏积分榜:

  • 10万用户
  • 分数实时变化
  • 需要展示Top 100
  • 需要查询用户自己的排名

方案:

用Redis ZSET:

  • key:game:ranking
  • value:用户ID
  • score:积分

用户积分变化时更新Redis,页面展示时直接从Redis获取。

这个方案能支撑百万级QPS,对于大部分场景足够了。

最后

排行榜是Redis的经典应用场景。

ZSET这个数据结构就是为排行榜而生的,用好了能解决大部分排行榜需求。

上次更新: 2025/12/7 09:34
Next
/tech-learning/system-design/elasticsearch-optimization.html