redis 压缩列表
压缩列表ziplist是列表、哈希和有序集合的底层实现,当数据量比较小时会使用ziplist。
列表类型ziplist条件:
- 列表对象保存的所有字符串元素都小于64字节;
- 列表对象保存的元素个数小于512个。
在配置文件中 list-max-ziplsit-entries和list-max-ziplist-value。
哈希类型ziplist条件:
- 哈希对象保存的所有字符串元素都小于64字节;
- 哈希对象保存的元素个数小于512个。
在配置文件中hash-max-ziplsit-entries和hash-max-ziplist-value。
有序集合ziplist条件:
- 有序集合保存的元素小于128个
- 所有元素长度小于64字节
在配置文件中zset-max-ziplsit-entries和zset-max-ziplist-value。
压缩列表结构
ziplist是特殊编码的一块连续内存的顺序性数据结构,非常节省内存的结构。
结构如下:
表头有三个字段 zlbytes、zltail 和 zllen,分别表示列表长度、列表尾的偏移量,以及列表中的 entry 个数。压缩列表尾还有一个 zlend,表示列表结束。
压缩列表之所以能节省内存,就在于它是用一系列连续的 entry 保存数据(减少了指针占用的空间)。
每个 entry 的元数据包括下面几部分。
- prev_len,表示前一个 entry 的长度。prev_len 有两种取值情况:1 字节或 5 字节。取值 1 字节时,表示上一个 entry 的长度小于 254 字节。虽然 1 字节的值能表示的数值范围是 0 到 255,但是压缩列表中 zlend 的取值默认是 255,因此,就默认用 255 表示整个压缩列表的结束,其他表示长度的地方就不能再用 255 这个值了。所以,当上一个 entry 长度小于 254 字节时,prev_len 取值为 1 字节,否则,就取值为 5 字节。
- len:表示自身长度,4 字节;
- encoding:表示编码方式,1 字节;
- content:保存实际数据。
压缩列表节点构成
压缩列表节点可以保存一个字节数组或整数值。
每个节点由previous_entry_length、encoding、content三部分组成
previous_entry_length:记录前一个节点的长度,因为记录前一个节点的长度,所以就可以根据当前节点的起始地址来计算前一个节点的起始地址。从表尾到表头遍历的原理。
encoding:记录了content属性的类型和长度。
content:保存节点的值,值可能是字节数组或整数,值的类型和长度由encoding决定。
连锁更新
在特殊情况下产生的连续多次空间扩展操作称之为“连锁更新”。
回顾
- 压缩列表是为节省内存而开发的顺序性结构
- 用于哈希和列表
- 压缩列表可以保存多个节点,每个节点可以是一个数组或整数
- 添加新节点或删除可能会引发连锁更新操作,但是几率不高。