一 前言
这篇博文用来解读 Redis 数据类型 List 的一种实现。数据结构 quicklist。虽然 List 类型有多种实现,但 quicklist 是最常用的。
quicklist 是一个双向链表,但同时也是一个复合的结构体。结构中包括了另一种结构 ziplist。如果不熟悉这种结构体,请先阅读这篇博文:《ziplist - 压缩列表》。
文中介绍了 ziplist 是一种十分节省内存的结构,紧凑的内存布局、变长的编码方式在内存使用量上有着不小的优势。但是修改操作下并不能像一般的链表那么容易,需要从新分配新的内存,然后复制到新的空间。
所以结合了 ziplist 节省内存和双向链表优点的 quicklist 产生了。
二 源码解读
2.1 quicklist
在 quicklist.c 中可以找到名为 quicklist 的结构体:
typedef struct quicklist {
quicklistNode *head;
quicklistNode *tail;
unsigned long count;
unsigned long len;
int fill : QL_FILL_BITS;
unsigned int compress : QL_COMP_BITS;
unsigned int bookmark_count: QL_BM_BITS;
quicklistBookmark bookmarks[];
} quicklist;
这个结构体定义了 quicklist 的布局,在 64 位的操作系统中它使用了 40 字节。看起来不是很复杂。结构中的各项代表含义如下:
- quicklistNode:32字节的结构体,用于描述 ziplist 的节点。这里很明显的体现了 quicklist 是一个复合的数据类型,在本版本中是且包含了 ziplist 的,未来可能会出现其他的结构体作为选项。
- count:记录所有节点中 ziplist 的所有 entry 的数量。比如有 2 个节点,每个节点中 ziplist 有 3 个 entry 。那这个值就是 6。
- len: 记录所有节点的数量。
- fill:记录控制节点中 ziplist 的最大 entry 个数,由参数 list-max-ziplist-size 控制。
- compress :记录控制 quicklist 左右两边 quicklistNode 不被压缩的个数,由参数 list-compress-depth 控制。取 0 时候代表不压缩,大于0 代表前后分别被压缩的个数。
- bookmark_count :记录数组 bookmarks[] 的长度。Redis 高版本 6.0 才新加的。
- bookmarks :quicklist重新分配内存空间时使用,否则只是声明不张占用内存空间。同样也是 6.0 后新增。
2.2 quicklistNode
接下来继续解读用来描述 ziplist 的 quicklistNode 结构,同样在在 quicklist.c 中可以找到名为 quicklistNode 的结构体:
typedef struct quicklistNode {
struct quicklistNode *prev;
struct quicklistNode *next;
unsigned char *zl;
unsigned int sz;
unsigned int count : 16;
unsigned int encoding : 2;
unsigned int container : 2;
unsigned int recompress : 1;
unsigned int attempted_compress : 1;
unsigned int extra :
Redis List数据类型实现:快速列表quicklist详解

本文深入解析Redis List数据类型的一种实现——快速列表quicklist。quicklist是一个结合了双向链表和压缩列表ziplist的复合结构,旨在平衡空间和时间复杂度。文章介绍了quicklist的结构、节点quicklistNode的组成、压缩情况以及操作接口,强调了合理配置节点内ziplist的entry数量以优化性能的重要性。
最低0.47元/天 解锁文章
&spm=1001.2101.3001.5002&articleId=117603534&d=1&t=3&u=fe611fc585c24f62bada73b3dea5a27b)
1145





