当前位置: 首页 > news >正文

如何简单实现排行榜功能

如何简单实现排行榜功能

      • 一、 基础方案:数据库直接排序(适合数据量小/低频更新)
      • 二、 主流方案:Redis Sorted Set (ZSET)
        • 核心操作:
        • 优化技巧:
      • 三、 超大规模方案:分布式解决方案
        • 1. 分层存储架构
        • 2. 近似排名算法 (节省内存)
        • 3. Lambda架构处理更新
      • 四、 业务策略增强
      • 五、 性能压测指标参考
      • 经典代码示例(Redis+Python)
      • 决策树:如何选择方案?

实现排行榜功能需要平衡 实时性、性能、扩展性数据一致性。以下是不同场景下的核心方案与技术选型:


一、 基础方案:数据库直接排序(适合数据量小/低频更新)

-- 按积分降序排名 (简单但性能差)
SELECT user_id, score, RANK() OVER (ORDER BY score DESC) AS rank 
FROM user_scores 
LIMIT 100;

缺点

  • 全表扫描 + 排序,数据量大时性能急剧下降
  • 高并发请求会压垮数据库

二、 主流方案:Redis Sorted Set (ZSET)

Redis 的 ZSET 是排行榜的黄金方案,支持 O(log N) 复杂度的插入/更新和 O(1) 的排名查询。

核心操作:
# 添加/更新用户积分
ZADD leaderboard 5000 "user_123"  # 查询用户排名 (从0开始, 需+1)
ZREVRANK leaderboard "user_123"  # 返回名次索引(降序)# 查询用户积分
ZSCORE leaderboard "user_123"# 获取TOP 100
ZREVRANGE leaderboard 0 99 WITHSCORES  # 降序取前100名# 分段查询 (第101~200名)
ZREVRANGE leaderboard 100 199 WITHSCORES
优化技巧:
  1. 冷热数据分离

    • 活跃用户存 Redis,全量数据定期同步到 DB(如 MySQL)
    • 用定时任务将 Redis TOP N 数据持久化
  2. 内存压缩

    • 用户ID用数字代替字符串(如 ZADD leaderboard 5000 123
    • 启用 Redis 的 zset-max-ziplist-entries 压缩小集合
  3. 分片存储 (Sharding)
    当单机内存不足时:

    • 按业务拆分:多个排行榜(如日榜/周榜)
    • 按范围分片leaderboard:shard1 (0~1000分), leaderboard:shard2 (1001~5000分)
    • 按Hash分片user_id % 16 分散到16个ZSET

三、 超大规模方案:分布式解决方案

当数据量超亿级(如全球游戏玩家)时,需组合以下技术:

1. 分层存储架构
客户端
API网关
Redis缓存 TOP 10,000
分布式计算引擎
S3/HDFS 全量数据
2. 近似排名算法 (节省内存)
  • T-Digest:维护数据分布模型,计算近似排名(误差<1%)
  • Redis Module RedisRank:支持亿级数据排名,内存占用仅为ZSET的1/10
3. Lambda架构处理更新
  • 实时层:Redis 处理最新排名(高频更新)
  • 批处理层:Spark/Flink 每日全量计算排名
  • 服务层:合并实时与离线结果

四、 业务策略增强

  1. 防止作弊

    • 积分变更记录审计日志
    • 异常分数变化检测(如单日增长超阈值)
  2. 并列排名处理

    # Python示例:ZSET同分时按时间戳排序
    timestamp = int(time.time() * 1000)  # 毫秒时间戳
    redis.zadd("leaderboard", { "user_123": f"{score}.{9999999999 - timestamp}" })
    

    查询时解析分数:score_str.split('.')[0]

  3. 多维度排行榜

    • 创建多个ZSET:leaderboard:daily, leaderboard:weekly
    • 使用 ZUNIONSTORE 合并多个榜单权重
  4. 冷启动优化

    • 预加载昨日TOP 1w数据到Redis
    • 首次查询时异步加载全量数据

五、 性能压测指标参考

场景QPS要求延迟要求推荐方案
小型应用(<10万用户)1,000<50msRedis ZSET 单机
中型应用(百万用户)10,000+<20msRedis Cluster + 分片
超大型(亿级用户)100,000+<100ms分层存储 + 近似排名算法

经典代码示例(Redis+Python)

import redis# 连接Redis集群
r = redis.RedisCluster(host='redis-cluster', port=6379)def update_score(user_id: int, delta: int):# 原子性增加积分r.zincrby("leaderboard", delta, user_id)def get_ranking(user_id: int) -> int:# 返回排名 (从1开始)rank = r.zrevrank("leaderboard", user_id)return rank + 1 if rank is not None else Nonedef get_top_n(n: int) -> list:# 获取TOP N [ (user_id, score), ... ]return r.zrevrange("leaderboard", 0, n-1, withscores=True)

决策树:如何选择方案?

graph TD
A[数据规模] -->|小于100万| B[Redis ZSET单机]
A -->|100万~1亿| C[Redis Cluster分片]
A -->|大于1亿| D[分层存储+近似排名]
B --> E[QPS<5万?]
C --> F[QPS<20万?]
D --> G[定制分布式方案]

关键建议:95%的场景用 Redis ZSET + 合理分片 即可满足需求,优先验证此方案!

http://www.dtcms.com/a/337790.html

相关文章:

  • 【数模国奖冲刺】备赛过程中的常见问题
  • Tomcat Engine 原理深度解析
  • python的电影院座位管理可视化数据分析系统
  • 宋红康 JVM 笔记 Day05|运行时数据区内部结构、JVM中的线程说明、程序计数器
  • linux系统查看ip命令
  • 【自动化测试】Selenium详解-WebUI自动化测试
  • 【智慧工地源码】智慧工地云平台系统,涵盖安全、质量、环境、人员和设备五大管理模块,实现实时监控、智能预警和数据分析。
  • 《清华级防护,了解一下?》
  • 局域网视频软件BeeWorks,内网顺畅沟通
  • FPGA学习笔记——IIC协议简介
  • ​​​​​​​专精特新企业数据(附参考文献, 2013-2023)
  • [openvela] Hello World :从零开始的完整实践与问题复盘
  • linux-高级IO(中)
  • Python数据容器(列表,元组,字典) 从入门到精通
  • 基于Python的就业信息推荐系统 Python+Django+Vue.js
  • 封装,继承,多态
  • 【CV 目标检测】Fast RCNN模型③——模型训练/预测
  • day44_2025-08-18
  • iOS 性能监控全流程实践,从开发到上线的多工具组合方案
  • RabbitMQ ,消息进入死信交换机
  • QT 字节大小端转序方法
  • Qt5基础控件详细讲解
  • VSCode REST Client 使用总结
  • 【力扣-轮转数组 Java / Python】
  • leetcode415. 字符串相加
  • 【论文阅读】-《HopSkipJumpAttack: A Query-Efficient Decision-Based Attack》
  • Jenkins全链路教程——Jenkins调用Maven构建项目
  • 北京朝阳公园——夏日清凉来袭
  • 第7节 神经网络
  • 登上Nature!清华大学光学神经网络研究突破