验证list、hash、zset三种类型的小集合,OBJECT ENCODING是不是真的都统一显示listpack,以及变大之后它们各自走向了哪条路。
list、hash、zset历史上各自有自己的"紧凑编码",验证它们现在是不是统一了。
操作RPUSH mylist a b c HSET myhash f1 v1 f2 v2 ZADD myzset 1 a 2 b OBJECT ENCODING mylist / myhash / myzset
结果没有一个是"ziplist"。
结果OBJECT ENCODING mylist → :listpack OBJECT ENCODING myhash → :listpack OBJECT ENCODING myzset → :listpack
三种类型用的都是同一个名字——listpack。老版本Redis(7.0之前)这三种类型小数据量时用的是各自独立实现的 ziplist,本文这个Redis 8.10.1已经完全看不到ziplist这个词了——listpack是一种更新、更省内存、编码修复更简单的紧凑结构,统一取代了ziplist在list/hash/zset三个类型里的角色。
同样从listpack出发,超过各自的阈值后,转成了三种不同的大集合结构。
结果(把三个阈值都手动设成64做对照)list超过阈值 → :quicklist(listpack节点组成的链表) hash超过阈值(65个字段) → :hashtable(真正的哈希表) zset超过阈值(65个成员) → :skiplist(跳表 + 哈希表的组合)
虽然小数据量时三者共享同一个 listpack 编码,但变大之后,各自转向的目标结构完全不同:list变成quicklist(很多个listpack节点串成的链表,适合频繁在两端插入/删除);hash变成hashtable(标准哈希表,适合大量字段的O(1)随机访问);zset变成skiplist(跳表配合哈希表,既要能按分数排序范围查询,又要能O(1)按成员查分数)。
每一步都是本文上面用redis-cli跑出来的原始结果。
OBJECT ENCODING:对比list/hash/zset的小/大集合编码