当前位置: 首页 > 后端技术 > Java

5分钟看懂Redis快速列表(quicklist)内部实现

时间:2023-04-01 15:52:04 Java

快速列表介绍在Redis3.2版本之前,存储列表(list)数据结构使用压缩列表(ziplist)和链表(linkedlist),当列表elements当数量比较少,每个元素占用空间较小时,使用压缩列表。当列表元素数量较多或某个元素占用空间较大时,使用链表。考虑到链表的附加空间比较高,节点的内存也是单独分配的,影响了内存管理的效率。在Redis3.2版本中,对列表数据结构进行了改造,使用快速列表(quicklist)代替了压缩列表(ziplist)和链表(linkedlist)。快速列表(quicklist)是一个以压缩列表(ziplist)为节点的链表(linkedlist)。链表被分成段。每个段使用压缩列表进行连续的内存存储。多个压缩列表是双向的,由prev和next指针组成。链表。它结合了压缩列表和链表的优点,进一步压缩了内存占用,进一步提高了效率。下面我们来看一下快速列表的具体实现。快速列表的实现Redis中的快速列表是用quicklist结构来表示的。quicklist结构包含一个由多个quicklist节点组成的双向链表,每个quicklist节点保存一个压缩列表。让我们一一仔细看看。quicklist结构quicklist用quicklist结构表示,它包含以下属性:head属性:指向headquicklist节点的指针。tail属性:指向尾部快速列表节点的指针。count属性:所有压缩列表中元素个数的总和。len属性:快速列表节点的个数。fill属性:压缩列表的最大尺寸,存放list-max-ziplist-size参数的值。当超过此配置时,将创建一个新的压缩列表。compress属性:节点压缩深度,存放list-compress-depth参数的值。bookmarks属性:用于快速列出重新分配内存空间时使用的数组,不使用时不占用空间。bookmark_count属性:书签数组的大小。快速列表节点快速列表节点由quicklistNode结构表示,它包含以下属性:prev属性:指向上一个快速列表节点的指针。next属性:指向下一个快速列表节点的指针。zl属性:指向压缩列表的指针,如果当前节点的数据是压缩的,则指向一个quicklistLZF结构。sz属性:压缩列表占用的总字节数。count属性:压缩列表中元素的个数。编码属性:存储形式,原生字节数组或LZF压缩存储。recompress属性:当查看某项压缩数据时,数据需要临时解压。这个时候设置recompress=1来标记一下,等有机会再重新压缩数据。quicklistLZF结构当quicklist节点数据被压缩后,数据会存储在quicklistLZF结构中,它包含以下属性:sz属性:表示压缩后的大小。compressed属性:存储压缩后的字节数组。快速列表的压缩机制在快速列表中,访问两端节点数据的可能性比较高,访问中间节点数据的可能性比较低。如果我们的应用场景满足这个特点,可以使用LZF算法对中间节点的数据进行压缩,进一步节省内存空间。我们可以配置list-compress-depth参数。list-compress-depth参数默认为0,即不压缩数据;当该参数设置为1时,除head和tail外的所有节点都会被压缩;当此参数设置为2时,除head、head的next、tail和tail的previous之外的所有节点都将被压缩;当这个参数设置为2时,除了head,head的next,head的next,next以外的nodes,tail,tail的previous,tail的previous的previous将会是压缩;等等。最后,谢谢你这么帅,给我点赞和关注。