在早期的版本中,数据量较小时用ziplist 存储,达到临界值时转换为linkedlist 进行存储,分别对应OBJ_ENCODING_ZIPLIST 和OBJ_ENCODING_LINKEDLIST 。
3.2 版本之后,统一用quicklist 来存储。quicklist 存储了一个双向链表,每个节点都是一个ziplist。
127.0.0.1:6379> object encoding queue
"quicklist"
quicklist
quicklist(快速列表)是ziplist 和linkedlist 的结合体。
quicklist.h,head 和tail 指向双向列表的表头和表尾
typedef struct quicklist {
quicklistNode *head; /* 指向双向列表的表头*/
quicklistNode *tail; /* 指向双向列表的表尾*/
unsigned long count; /* 所有的ziplist 中一共存了多少个元素*/
unsigned long len; /* 双向链表的长度,node 的数量*/
int fill : 16; /* fill factor for individual nodes */
unsigned int compress : 16; /* 压缩深度,0:不压缩; */
} quicklist;
redis.conf 相关参数:
参数 | 含义 |
list-max-ziplist-size(fill) | 正数表示单个ziplist 最多所包含的entry 个数。 负数代表单个ziplist 的大小,默认8k。 -1:4KB;-2:8KB;-3:16KB;-4:32KB;-5:64KB |
list-compress-depth(compress) | 压缩深度,默认是0。 1:首尾的ziplist 不压缩;2:首尾第一第二个ziplist 不压缩,以此类推 |
quicklistNode 中的*zl 指向一个ziplist,一个ziplist 可以存放多个元素。
typedef struct quicklistNode {
struct quicklistNode *prev; /* 前一个节点*/
struct quicklistNode *next; /* 后一个节点*/
unsigned char *zl; /* 指向实际的ziplist */
unsigned int sz; /* 当前ziplist 占用多少字节*/
unsigned int count : 16; /* 当前ziplist 中存储了多少个元素,占16bit(下同),最大65536 个*/
unsigned int encoding : 2; /* 是否采用了LZF 压缩算法压缩节点,1:RAW 2:LZF */
unsigned int container : 2; /* 2:ziplist,未来可能支持其他结构存储*/
unsigned int recompress : 1; /* 当前ziplist 是不是已经被解压出来作临时使用*/
unsigned int attempted_compress : 1; /* 测试用*/
unsigned int extra : 10; /* 预留给未来使用*/
} quicklistNode;
ziplist 的结构前面已经说过了,不再重复。