跳表 + 字典的完美组合
2010 年,Zset(有序集合)诞生。底层使用 ziplist 实现, member 和 score 成对存储,按 score 有序排列。
确立 ziplist 的使用条件。当元素数量不超过 zset-max-ziplist-entries 且每个元素长度不超过 zset-max-ziplist-value 时使用 ziplist。
优化 ZRANGEBYSCORE 等范围查询命令的性能。 ziplist 的二分查找机制确保 O(log n) 的范围定位。
革命性突破!引入 skiplist(跳表)和 dict(字典)组合作为 Zset 的高性能底层实现。 skiplist 保证有序,dict 保证 O(1) 单点查询。
调整 zset-max-ziplist-entries 从 128 → 128(保持), 优化跳表的随机层数生成算法,保持结构稳定。
将 zset-max-ziplist-entries 从 128 → 128, 但优化了内部实现,提升 ZRANK/ZREVRANK 等排名查询的性能。
Redis 7.0 将 Zset 的 ziplist 替换为 listpack。 skiplist + dict 组合保持不变,只是 ziplist 部分升级为 listpack。
同一份数据,两种访问路径:字典 O(1) 查询 + 跳表 O(log n) 范围
Redis Zset 的演进是"鱼与熊掌兼得"的典范:
按序存储(范围查询)+
O(1) 查询(单点定位)=
skiplist + dict
核心设计哲学:
空间换时间 — 两份索引,但都是指针
自动切换 — 小数据用 listpack 省内存
各司其职 — skiplist 管有序,dict 管去重+快速查询
这就是为什么 Zset 能同时支持"排行榜"(ZRANGE)和"实时分数"(ZSCORE)两种高频场景。