压缩列表是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么就是整数值,要么就是长度比较短的字符串,那么redis就会使用压缩列表来做列表键的底层实现。
压缩列表的构成
压缩列表是redis为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型数据结构。一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值。
上图就是一个压缩列表的结构,我们来看一下每部分的作用
typedef struct zlentry {
// prevrawlen :前置节点的长度
// prevrawlensize :编码 prevrawlen 所需的字节大小
unsigned int prevrawlensize, prevrawlen;
// len :当前节点值的长度
// lensize :编码 len 所需的字节大小
unsigned int lensize, len;
// 当前节点 header 的大小
// 等于 prevrawlensize + lensize
unsigned int headersize;
// 当前节点值所使用的编码类型
unsigned char encoding;
// 指向当前节点的指针
unsigned char *p;
} zlentry
这是一个压缩列表的节点
previous_entry_length:记录了前一个节点的长度,它可以是1字节或5字节
如果前一个节点的长度小于254字节,那么previous_entry_length属性的长度为 1字节;前一个节点的长度就保存在这一个字节里面
如果前一个字节的长度大于等于254字节,那么previous_entry_length属性的长度为5字节:其中属性的第一个字节会被设置为0xFE,而之后的四个字节则用于保存前一节点的长度
通过这个属性,我们就可以实现从尾到头遍历整个压缩列表
encoding:记录了节点的content属性所保存数据的类型以及长度
content:保存节点的值,节点值可以是一个字节数组或者整数,值的类型 和长度由节点的encoding属性决定