← 每日面试题 学习看板

Redis的zset实现排行榜,实现分数相同按照时间顺序排序,怎么做?

面试题/01实践场景题/实践场景题目/缓存与Redis应用/Redis的zset实现排行榜,实现分数相同按照时间顺序排序,怎么做?.md

面试记录 2026-10-15

题目:Redis的zset实现排行榜,实现分数相同按照时间顺序排序,怎么做?

难度:high

评分:⭐⭐⭐⭐☆☆(3/5)

我的回答

zset的排序规则只支持分数排序,如果要实现相同分数按照时间排序有两种思路,一个是在分数的后面跟上时间戳,作为分数的补充内容一起进行排序,另外就是在 zset 的 value 中保存时间,读取相同分数的内容后,在业务端进行二次排序,都能实现同分数后按照其他规则排序

点评

优点:

两种思路都提到- 分数拼接方案抓到

不足:

❌ 遗漏分数拼接具体实现(如 score * 1e13 + timestamp)- ❌ 遗漏时间戳精度选择(毫秒 vs 微秒)- ❌ 遗漏同毫秒内排序边界情况- ❌ 遗漏业务端二次排序在分页场景的代价- ❌ 遗漏排行榜扩展(Top N、我的排名、实时推送)

完整讲解

第一部分:知识重点剖析

核心考点:考察 Zset 排行榜的工程化实现能力,理解分数拼接技巧。

知识点拆解:

  1. 问题背景:Zset 按分数排序,分数相同时按 member 字典序排序(不稳定)。业务需要分数相同时按时间排序。
  2. 方案一:分数拼接
  1. 方案二:业务端二次排序
  1. 方案三:分数分段
  1. 排行榜常见扩展:

关键命令:

第二部分:考察方向与延伸递进

  1. 分数拼接的时间戳精度怎么选?
  1. 同毫秒内多个用户分数相同怎么排?
  1. 排行榜如何支持实时更新?

第三部分:面试者参考回答(300-600 字口语化)

面试官您好,Zset 排行榜分数相同按时间排序有两种方案。

方案一是分数拼接:分数 = 业务分数 × 1e13 + 时间戳(毫秒)。例如分数 100,时间戳 1690000000000,拼接后是 10016900000000000。Zset 原生支持,查询高效。缺点是时间戳精度限制,毫秒内无法区分。

方案二是业务端二次排序:Zset 存 score + member,member 中包含时间戳,读取后在业务端排序。灵活,支持任意排序规则。缺点是分页场景困难(需加载全部数据)、性能差。

我推荐方案一,分数拼接。时间戳用毫秒够用,同毫秒概率极低,不影响业务。

排行榜常见扩展:Top N 用 ZREVRANGE 0 N-1,我的排名用 ZREVRANK O(log n),分数变化用 Pub/Sub 或 Redis Stream 推送,分维度(实时/小时/日/周榜)用多个 Zset。

生产实践:Top 1000 排行榜,分数拼接毫秒时间戳,ZADD 更新分数,Pub/Sub 推送变化,客户端订阅实时更新。分维度排行榜用多个 Zset,每个 Zset 独立过期时间。