惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 郭慕荣

Docker部署zookeeper总结 Mac中git ssh的配置(GitLab) Java 类加载机制 面试题(一) 如何监控和调优JVM性能? jvm常用的参数有哪些? 怎么配置? hashmap 和currenthashmap 的原理?详解一下 aop在项目中使用的场景?怎么使用? Java dubbo spring springboot中的spi机制 spring中常见的两种代理模式 drools 规则引擎在线化配置 - 郭慕荣 springcloud中常用的注解详解 springcloud中网关gateway总结 spring是怎么解决循环依赖的? MySQL 死锁 怎么处理? 在写left join的时候 是大表在左侧 还是小表在左侧(二) 在写left join的时候 是大表在左侧 还是小表在左侧(一) nacos客户端(接口调用者)如何感知被调用服务下线? (二) nacos客户端(接口调用者)如何感知被调用服务下线?(一) 在MySQL中 redolog undolog binlog 写入的场景,顺序 - 郭慕荣
Redis的zset 面试汇总
郭慕荣 · 2025-10-25 · via 博客园 - 郭慕荣

🧠 一、ZSet 是什么?

ZSet(Sorted Set)= 有序集合

  • 元素 不重复(唯一 key),但可以有相同的分值(score)。

  • 元素按照 score 从小到大排序

  • 支持按 score 范围 / 排名区间 查询,非常高效。

语法示例:

🧩 二、ZSet 的底层原理(重点考点)

ZSet 是 Redis 内部比较复杂的结构之一 —— 实际上是由 两种数据结构组合 实现的:

dict(哈希表) 存放成员到分值的映射(member → score) O(1) skiplist(跳表) 存放分值到成员的排序关系(score → member) O(logN)
组件作用复杂度

Redis 会同时维护这两个结构以保证:

  • 通过成员快速查找分值(dict)

  • 通过分值范围快速排序和遍历(skiplist)

✅ 跳表(skiplist)原理简述

  • 跳表是一种多层链表结构,通过“多级索引”加速查找,类似于二分查找。

  • 时间复杂度:O(logN)

  • 插入、删除、范围扫描都非常高效。

跳表示意:

⚙️ 三、常用命令与时间复杂度

插入/更新 ZADD key score member O(logN) 若成员存在则更新分值 删除 ZREM key member O(logN) 同时从 dict 与 skiplist 删除 按分值范围查 ZRANGEBYSCORE key min max O(logN + M) M 为返回数量 按排名范围查 ZRANGE key start stop O(logN + M) 支持逆序 查成员分值 ZSCORE key member O(1) 从 dict 查 查排名 ZRANK key member O(logN) 从 skiplist 查 增加分值 ZINCRBY key increment member O(logN) 自动更新位置 删除区间 ZREMRANGEBYSCORE key min max O(logN + M) 范围删除 集合并集 ZUNIONSTORE / ZINTERSTORE O(N logN) 分值加权合并
操作命令时间复杂度说明

🚀 四、使用场景(高频面试题)

✅ 1. 排行榜系统(最经典)

场景: 游戏积分榜、电商热度榜、内容点赞排行等
设计:

优势:

  • 实时更新分值。

  • 可快速取前 N 名、后 N 名、某区间段。

✅ 2. 延迟队列(基于 score 存时间戳)

场景: 定时任务、重试队列、延迟通知等

思路:

  • score = 任务执行时间戳

  • 定时轮询当前时间 ≤ score 的任务

优点:

  • 不依赖外部消息系统

  • 可控制延迟精度(秒级)

✅ 3. 热点数据 Top-N

场景: 内容推荐、最热文章、热门搜索词
思路:

  • 每次访问调用 ZINCRBY 累加热度

  • 定时取前 N 名显示

✅ 4. 权重队列 / 任务优先级

场景: 风控任务、风控规则优先级处理

  • score = 权重(越高优先级越高)

  • ZPOPMAX 每次取最高优先级任务处理

✅ 5. 用户活跃度 / 打分系统

  • 用户行为打分、信用评分、综合指标

  • 可存历史分数,定期做 decay(衰减)

💡 五、ZSet 的优缺点

有序、可快速范围查询 按分值排序,支持分页、区间 插入、删除、查找效率高 跳表 O(logN) 支持原子操作 不需要事务就能安全并发修改 数据量大也能稳定性能 比 list 链表结构高效
优势说明
内存占用较高 维护 skiplist + dict 无法去重按值排序(只能按 score) 需自行定义 score 规则 不支持按 value 排序 必须以 score 为序
缺点说明

🧮 六、与其他数据结构对比(面试延伸题)

String 否 是(键唯一) O(1) KV 存储 List 按插入顺序 可重复 O(N) 消息队列 Set 无序 唯一 O(1) 去重集合 ZSet ✅ 有序 ✅ 唯一 O(logN) 排行榜、延迟队列、TopN
类型是否排序是否唯一查询复杂度典型场景

🧠 七、面试高频问法(及标准答法)

① ZSet 底层实现是什么?

跳表(skiplist)+ 哈希表(dict)。
跳表用于按分值排序,哈希表用于 O(1) 查找分值。

② 插入和查询的复杂度是多少?

O(logN) 插入,O(1) 查找,O(logN+M) 范围查。

③ 为什么不用红黑树?

Redis 选择跳表主要因为:

  • 插入/删除更简单;

  • 实现更直观;

  • 更适合范围遍历;

  • 占用内存少,性能稳定。

④ 怎么实现延迟队列?

score 存未来执行时间戳,定期 ZRANGEBYSCORE 拉取可执行任务。

⑤ 怎么实现排行榜 TopN?

score 存积分,ZREVRANGE 取前 N 名。

⑥ 如果有 1 亿个用户,取前 100 名怎么优化?

用 ZSet 存局部排行榜 + 分片聚合;
或者采用 Top-K 算法(如 Min-Heap)+ 定期同步 Redis。

🧰 八、实战优化建议

  • ⚙️ pipeline 批量写入:避免多次网络往返。

  • 🧩 热榜分层缓存:TopN 存本地内存,底层数据异步更新。

  • 🔄 分布式排行榜:按业务分片多个 ZSet,合并时在应用层聚合。

  • 数据过期策略:结合 TTL 或周期性清理。

  • 💾 持久化:RDB/AOF 支持 ZSet,重启不丢失。

✅ 总结记忆卡

底层结构 dict + skiplist 复杂度 插入/删除 O(logN),查找 O(1) 常用命令 ZADD, ZRANGE, ZREVRANK, ZINCRBY, ZREMRANGEBYSCORE 典型场景 排行榜、延迟队列、TopN、权重队列 优势 有序、高性能、原子操作 缺点 内存占用较高,按 value 排序不支持
模块内容