Sorted Set 排行榜如何处理同分、翻页与历史榜单
我早期做活动榜时,直接把 ZREVRANK + 1 当成用户名次,直到产品问“两个同分的人为什么一个第 2、一个第 3”。这不是 Redis 排错了,而是我们把“集合中的确定位置”误当成“业务展示名次”。更稳妥的规则是:Sorted Set 负责唯一成员、分数和稳定顺序;同分名次、翻页一致性与历史周期由业务协议补齐。
Redis 官方文档:https://redis.io/docs/latest/develop/data-types/sorted-sets/
- 同分成员在 Redis 内仍按成员字符串排序,逆序查询时使用逆字典序。
- 实时榜可以按位置分页,但必须承认更新会让页边界移动。
- 历史榜最好从一开始就写入周期键,而不是结束时临时复制。
旧规则的问题:位置不等于并列名次
Sorted Set 的成员唯一,每个成员关联一个浮点分数。分数不同就按分数排序;分数相同则按成员字符串的字典序决定先后。ZRANGE ... REV 会把高分放前面,并反转同分成员的字典序。因此 Redis 能给同分用户不同的零基位置,但它并不知道产品想显示“1、2、2、4”还是“1、2、2、3”。
# 两名用户同为 980 分,Redis 仍会为成员保留确定顺序
redis-cli ZADD 'lb:{game}:2026-W41' 1050 'u:1000' 980 'u:1001' 980 'u:1002' 910 'u:1003'
# 取高分在前的榜单;同分顺序由成员字符串决定
redis-cli ZRANGE 'lb:{game}:2026-W41' 0 -1 REV WITHSCORES
# 返回的是零基位置,不是“同分同名次”的业务排名
redis-cli ZREVRANK 'lb:{game}:2026-W41' 'u:1001'

新规则:用更高分人数计算竞赛排名
如果展示规则是竞赛排名“1、2、2、4”,某成员的名次应等于“严格高于它的成员数 + 1”。ZCOUNT 的边界默认包含端点,给分数加 ( 前缀即可排除当前分数。下面 980 分的两名用户都只看到一名更高分用户,因此都显示第 2 名。
# 统计严格高于 980 分的成员;(980 表示不包含 980
redis-cli ZCOUNT 'lb:{game}:2026-W41' '(980' '+inf'
# 应用层把返回值加 1,得到并列竞赛名次
# 若一页包含多个分数,可按不同分数去重后用 pipeline 批量查询
我不建议把时间戳硬塞进小数位来“打破同分”。那会悄悄改变分数语义,还把展示规则绑死在编码技巧里。若业务确实需要先到先得,就把时间规则明确成产品规则,并单独设计可解释的复合排序数据,而不是假装大家仍然同分。
翻页的新语义:实时榜允许变化,但要可检测
按位置分页最直接:第 1 页取 0–19,第 2 页取 20–39。官方文档也提醒,大偏移量需要先遍历前面的元素,代价可能上升到 O(N)。更重要的是,用户翻页期间只要有人加分,页边界就可能移动,出现重复或遗漏。对实时榜,我会返回一个版本号;下一页请求若发现版本变化,就提示刷新或从第一页重新开始。
# 分数和榜单版本放在同一连接的事务中更新 redis-cli
严格连续、不重不漏的翻页不适合在持续写入的同一个榜单上强行保证。报表导出或审计查询应读取冻结的周期榜;实时榜只保证“某次请求时刻的一个窗口”,并把变化显式告诉调用方。
历史榜单的新模型:周期键本身就是快照
与其周日夜里复制一个不断写入的 live 键,我更喜欢把周期写进 key:lb:{game}:2026-W41。应用根据统一时区算出当前周期,整个周期只写这个键;周期结束后停止写入,它自然成为历史榜。花括号中的 {game} 还能让相关键在 Redis Cluster 中使用同一哈希标签。
# 当前周期持续累加,成员使用稳定用户 ID
redis-cli ZINCRBY 'lb:{game}:2026-W41' 30 'u:1004'
# 周期关闭后设置 90 天保留期;到期后 Redis 自动删除该历史键
redis-cli EXPIRE 'lb:{game}:2026-W41' 7776000
# 查询历史榜与实时榜使用同一种范围接口,只替换周期参数
redis-cli ZRANGE 'lb:{game}:2026-W41' 0 19 REV WITHSCORES

周期切换要统一时区,并让旧周期进入只读状态。若业务允许迟到积分,应定义补写窗口以及是否同步修正已展示的历史名次;这属于产品规则,不能由 Redis 命令替你决定。
常见问题
同分时能直接使用 ZREVRANK 吗? 可以用于唯一位置榜,但不能用于“同分同名次”。后者需要基于严格更高分人数计算展示名次。
为什么不用分数游标翻页? 只保存 score 的游标无法区分一大组同分成员;持续写入时也无法保证稳定边界。需要严格一致时,应读取冻结周期键或专门生成快照。
历史榜设置 TTL 后继续 ZINCRBY 会丢失 TTL 吗? 修改现有数据结构内容通常不会清除超时,但关闭周期后仍应禁止业务写入,避免历史结果变化。
RWMutex 一定比 Mutex 快吗,怎样根据临界区做选择
- 上一篇
- RWMutex 一定比 Mutex 快吗,怎样根据临界区做选择
- 下一篇
- 借助 OnceValue 延迟构造共享配置并传播初始化错误
-
- 数据库 · Redis | 5小时前 | Redis · 消息队列 · 消息重试 XPENDING XAUTOCLAIM Redis Streams XTRIM 消费者组积压
- Streams 消费者组积压怎么处理:认领、重试与裁剪
- 324浏览 收藏
-
- 数据库 · Redis | 7小时前 |
- Redis Vector Set 做语义检索:向量、元数据与过滤条件
- 195浏览 收藏
-
- 数据库 · Redis | 11小时前 | Redis ·
- Redis MEMORY STATS 里的 allocator_frag_ratio 怎么理解
- 348浏览 收藏
-
- 数据库 · Redis | 13小时前 | Redis · Redis ACL ACL DRYRUN ACL SETUSER Redis权限测试 键模式
- Redis ACL DRYRUN 怎么在授权前测试一条命令
- 288浏览 收藏
-
- 数据库 · Redis | 15小时前 |
- Redis SLOWLOG 和 LATENCY DOCTOR 应该分别看什么
- 208浏览 收藏
-
- 数据库 · Redis | 17小时前 |
- Redis 键空间通知为什么收不到过期事件
- 291浏览 收藏
-
- 数据库 · Redis | 20小时前 | lua · redis Redis Functions FUNCTION LOAD FCALL 版本发布
- Redis Functions 怎么用 FCALL 调用版本化逻辑
- 149浏览 收藏
-
- 数据库 · Redis | 22小时前 | Redis · redis CLIENT TRACKING BCAST 客户端缓存 OPTIN INVALIDATE
- Redis 客户端缓存怎么用 TRACKING 避免脏读
- 115浏览 收藏
-
- 数据库 · Redis | 1天前 | redis Redis Cluster 哈希标签 多键操作 槽位
- Redis Cluster 哈希标签怎么让多键操作落在同一槽
- 463浏览 收藏
-
- 数据库 · Redis | 1天前 | Redis · redis 向量检索 VSIM Vector Set EPSILON
- Redis Vector Set 怎么按相似度过滤结果
- 433浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 363次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 417次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 430次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 384次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 210次使用
-
- Go与Redis实现分布式互斥锁和红锁
- 2022-12-22 117浏览
-
- Go+Redis实现延迟队列实操
- 2023-02-23 426浏览
-
- 一文搞懂Go语言操作Redis的方法
- 2023-01-07 171浏览
-
- Golang分布式应用之Redis示例详解
- 2023-01-07 113浏览
-
- Go Redis客户端使用的两种对比
- 2022-12-30 195浏览

