相关文章1

存储原理

Redis3.2之前,列表对象其底层存储结构可以有两种,即:linkedlistziplist,而在Redis 3.2之后,列表对象底层存储结构优化成为了另一种:quicklist。而quicklist可以认为是linkedlist和ziplist的结合体。
image.png

当列表对象同时满足以下两个条件时,列表对象使用ziplist进行存储,否则用linkedlist存储。

  • 列表对象保存的所有字符串元素的长度小于64字节
  • 列表对象保存的元素数量小于512个。

linkedlist

linkedlist是一个双向列表,每个节点都会存储指向上一个节点和指向下一个节点的指针。linkedlist因为每个节点的空间是不连续的,所以可能会造成过多的空间碎片

image.png
image.png

ziplist

ziplist是为了节省内存而开发的一种压缩列表数据结构,后面讲述的哈希数据类型底层也用到了ziplist。

ziplist是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个ziplist可以包含任意多个entry,而每一个entry又可以保存一个字节数组或者一个整数值。

ziplist和linkedlist最大的区别是ziplist不存储指向上一个节点和下一个节点的指针,存储的是上一个节点的长度和当前节点的长度,牺牲了部分读写性能来换取高效的内存利用率,是一种时间换空间的思想。

ziplist适用于字段个数少和字段值少的场景。

ziplist存储结构
image.png
entry存储结构
image.png
prevlen
image.png
encoding
encoding属性存储了当前entry所保存数据的类型以及长度。encoding长度为1字节,2字节或者5字节长。前面我们提到,每一个entry中可以保存字节数组和整数,而encoding属性的第1个字节就是用来确定当前entry存储的是整数还是字节数组。当存储整数时,第1个字节的前两位总是11,而存储字节数组时,则可能是00、01和10。

  • 当存储整数时,第1个字节的前2位固定为11,其他位则用来记录整数值的类型或者整数值:

image.png

  • 当存储字节数组时,第1个字节的前2位为00、01或者10,其他位则用来记录字节数组的长度:

image.png
entry-data
entry-data:具体数据。当存储小整数时,encoding就是数据本身,此时没有entry-data部分,没有entry-data部分之后的ziplist结构如下:
image.png
image.png
ziplist连锁更新问题
image.png

quicklist 链表

image.png
image.png
image.png