Redis中的 QuickList
是一种特殊的数据结构,用于存储列表类型的数据。它的设计目的是在内存中高效地存储和操作大量的列表元素,尤其是当列表长度很大时。
QuickList的内部结构是一个由多个节点组成的双向链表,每个节点包含一个小的连续内存块,这些内存块被称为ziplist(压缩列表)。每个ziplist中存储了一个不定长度的元素序列,这些元素可以是字符串或整数。QuickList的每个节点都维护了指向上一个节点和下一个节点的指针,这样整个QuickList就形成了一个链表。
☃️前提概要
问题1:ZipList虽然节省内存,但申请内存必须是连续空间,如果内存占用较多,申请内存效率很低。怎么办?
答:为了缓解这个问题,我们必须限制ZipList的长度和entry大小。
问题2:但是我们要存储大量数据,超出了ZipList最佳的上限该怎么办?
答:我们可以创建多个ZipList来分片存储数据。
问题3:数据拆分后比较分散,不方便管理和查找,这多个ZipList如何建立联系?
答:Redis在3.2版本引入了新的数据结构QuickList,它是一个双端链表,只不过链表中的每个节点都是一个ZipList。
☃️ 配置项相关
为了避免QuickList中的每个ZipList中entry过多,Redis提供了一个配置项:list-max-ziplist-size来限制。
如果值为正,则代表ZipList的允许的entry个数的最大值
如果值为负,则代表ZipList的最大内存大小,分5种情况:
- -1:每个ZipList的内存占用不能超过4kb
- -2:每个ZipList的内存占用不能超过8kb
- -3:每个ZipList的内存占用不能超过16kb
- -4:每个ZipList的内存占用不能超过32kb
- -5:每个ZipList的内存占用不能超过64kb
其默认值为 -2:
☃️简要源码
以下是QuickList的和QuickListNode的结构源码:
我们接下来用一段流程图来描述当前的这个结构
☃️总结
QuickList的一些特点和优势:
分段存储: QuickList将列表分成多个节点,每个节点都包含一定数量的元素,这样可以降低内存碎片化的程度,提高内存利用率。
支持快速尾部插入和删除操作: 由于QuickList是一个双向链表,因此在列表的两端进行插入和删除操作的性能都很高,时间复杂度为O(1)。
压缩列表优化: QuickList中使用的ziplist是一种紧凑的数据结构,它可以在一定程度上减少内存的消耗。另外,ziplist还支持一些特殊的操作,比如在固定时间内查找元素、在固定时间内插入元素等。
灵活性: QuickList可以根据需要动态地调整节点的大小,从而适应不同大小的列表。这种灵活性可以帮助Redis在不同的工作负载下提供更好的性能。
总的来说,QuickList是Redis中用于存储列表类型数据的一种高效数据结构,它结合了双向链表和压缩列表的优点,在内存占用和性能方面都具有很好的表现。
QuickList的特点:
- 是一个节点为ZipList的双端链表
- 节点采用ZipList,解决了传统链表的内存占用问题
- 控制了ZipList大小,解决连续内存空间申请效率问题
- 中间节点可以压缩,进一步节省了内存