跳转至

ZSet 压缩列表和跳表如何选择

一、ZSet 的两种编码

  • ziplist(压缩列表):元素少、小。
  • skiplist(跳表):元素多、大。

二、ziplist 结构

一块连续内存,按 score 升序存:

[prevlen][encoding][score][member][prevlen][encoding][score][member]...
  • 没有链表指针,省内存。
  • 二分查找(内存连续)。

三、什么时候用 ziplist

zset-max-ziplist-entrieszset-max-ziplist-value

zset-max-ziplist-entries 128   # 元素数 ≤ 128
zset-max-ziplist-value 64       # 每个元素 ≤ 64 字节

满足两个条件,用 ziplist。

四、为什么

ziplist 优点

  • 连续内存,缓存友好。
  • 没有指针开销,省内存。

ziplist 缺点

  • 插入删除要移动内存(O(n))。
  • 元素多了性能差。

五、什么时候转 skiplist

元素数 > 128 或单个元素 > 64 字节,Redis 自动转 skiplist。

ziplist → skiplist(不可逆,除非删除)

六、为什么不一直用 skiplist

  • 跳表每个节点有多层指针,内存开销大。
  • 小数据集,跳表的多层索引是浪费。
  • ziplist 在小数据量下更快(缓存命中)。

七、对比

ziplist skiplist
内存 连续,省 指针多,费
查找 O(n) 但缓存好 O(log n)
插入 O(n) 移动内存 O(log n)
适用 小数据(≤128) 大数据

面试要点

  • 两个阈值都要满足才用 ziplist。
  • ziplist 是 Redis 早期设计,Redis 7.0 后 listpack 逐步替代。