压缩列表是列表键和哈希键的底层实现之一。当一个列表键只包含少许列表项,而且每一个列表项要么就是小整数,要么就是长度比较短的字符串,redis就会使用压缩列表来作列表键的底层实现redis
当一个哈希键只包含少许键值对,而且每一个键值对的键和值要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来作哈希键的底层实现。数组
压缩列表是Redis为了节约内存而开发的是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个压缩列表能够包含任意多个节点,每一个节点能够保存一个字节数组或者一个整数值数据结构
ziplist 数据结构编码
压缩列表节点的构成指针
每一个压缩列表节点能够保存一个字节数组或者一个整数值,其中字节数组能够是如下三种长度的其中一种blog
长度小于等于63字节的字节数组ip
长度小于等于16383字节的字节数组内存
长度小于等于4294967295字节的字节数组开发
数值则能够是如下六种长度的其中一种字符串
1: 4位长介于0至12之间的无符号整数
2:1字节长的有符号整数
3: 3字节长的有符号整数
4:int16类型整数
5:int32类型整数
6 : int64类型整数
压缩列表的数据结构
previous_entry_length 属性以字节为单位,记录了压缩列表中前一个节点的长度,previous_entry_length属性的长度能够是1字节或者5字节
若是前一节点的长度小于254字节那么previous_entry_length属性的长度为1字节 若是前一节点的长度大于等于254字节previous_entry_length属性的长度为5字节
根据当前节点的地址和previous_entry_length的值来计算出前一个节点的地址
压缩列表的从表尾向表头遍历操做就是使用这一原理实现的,只要咱们拥有了一个指向某个节点起始地址的指针,那么经过这个指针以及这个节点的previous_entry_length属性
程序就能够一直向前一个节点回溯,最终到达压缩列表的表头节点。
节点encoding属性记录了节点的content属性所保存数据的类型以及长度
一字节、两字节或者五字节长,值的最高位为00 、0一、或者10的是字节数组编码这种编码表示节点的content属性保存着字节数组,数组的长度有编码除去最高两位以后的其余位记录
一字节长 值的最高位以11开头的是整数编码,这种编码表示节点的content属性保存着整数值,整数值的类型和长度有编码除去最高两位以后的其余位记录
节点的content属性负责保存节点的值,节点值能够是一个字节数组或者整数值的类型和长度由encoding决定
连锁更新
连锁更新在最坏状况下须要对压缩列表执行N次空间重分配操做,而每次空间重分配的最坏复杂度为O(n) 连锁更新最坏的时间复杂度O(n*n)
lian