【redis学习笔记-01-基础篇】-04-压缩列表与快速列表

为什么要将压缩列表和快速列表放在一起?

什么是压缩列表,什么是快速列表?

要回答上面两个问题,在此之前我们先了解下redis的列表。

在之前的博客中有写到redis的5中基本数据类型,其中就包括 list ,也说过 list 本质上是个双向链表。我们可以把 list 做队列使用,也可以用 list 来做栈使用。具体应用操作可回顾之前文章。

【redis学习笔记-01-基础篇】-04-压缩列表与快速列表_第1张图片

 

redis出于空间利用率考虑,list 的双向链表结构分为压缩列表 和 快速列表。在数据量较少的时候会分配一块连续的存储用作压缩列表。当数据量较大时,redis会将存储结构改为快速列表。

 

list 结构中head 指向链表第一个节点,tail指向链表最后一个节点, len保存有链表的长度。这样在获取链表表头和表尾节点的时间复杂度为O(1)。 

 

压缩列表是内存上的一整块连续空间,其中包含了任意多个保存字节数组或者整数值的节点组成的数据结构。

【redis学习笔记-01-基础篇】-04-压缩列表与快速列表_第2张图片

上方所示为压缩列表的数据结构,其中

zlbtyes 为整个压缩列表占用的内存字节数;

zltail 为尾节点距离列表起始地址的偏移量,方便定位尾节点;

zllen 为节点 entry 的个数;

entry 为各节点;

zlend 为列表结尾标志。

 

entry 结构如下组成

【redis学习笔记-01-基础篇】-04-压缩列表与快速列表_第3张图片

prev_len 为当前 entry 节点的上一个节点的长度。因为记录了前一个节点的长度,所以可以通过节点的地址偏移量来计算出上一个节点的地址位置。整个属性是实现压缩列表从列尾向前遍历的关键。

content 保存了节点的值,content 保存的可以是一个字节数组,也可以是整数。

encoding 属性是对content的描述,可以记录content的长度,类型,甚至当节点值是小整数时,encoding 通过自身编码结构可以记录这个节点值。

 

快速列表是双向链表和压缩列表的结合,即双向链表的每一个节点其实是一个压缩列表。

因为纯的双向链表 prev 和 next指针占用一些字节空间,且大量的节点造成 prev 和 next 占用空间膨胀,且每个节点单独分配造成空间碎片增加。后面redis在新的版本中采用了压缩列表和双向列表结合的方式来改造列表的存储。其结构大致如下图所示:

【redis学习笔记-01-基础篇】-04-压缩列表与快速列表_第4张图片

快速列表节点的压缩列表默认长度为8KB,可通过list-max-ziplist-size参数配置,当超过这个字节数时,就会另起一个压缩列表。

 

 

你可能感兴趣的:(redis学习)