[Redis]快速列表详解

quicklist

Redis早期版本存储list列表数据结构使用的是压缩列表ziplist 和普通的双向链表linkedlist,也就是说当元素少时用ziplist,当元素多时用linkedlist。

//链表的节点
struct listNode<T>{
	listNode* prev;
	listNode* next;
	T value;
}
// 链表
struct list{
	listNode *head;
	listNode *tail;
	long length;
}

考虑到链表的附加空间相对太高,prev和next指针就要占去16个字节(64位操作系统的指针占8个字节),另外每个节点的内存都是单独分配,会加剧内存的碎片化,影响内存管理效率。
后来的 Redis 新版本对列表数据结构进行了改造,使用quicklist 代替了ziplist和linkedlist。

>rpush codehole go java python
(integer)3
>debug object codehole
Value at:0x7fec2dc2bde0 refcount:1 encoding:quicklist serializedlength:31 lru:6101643 lru_seconds_idle:5 ql_nodes:1 qlavg_node:3.00 ql_ziplist_max:-2 ql_compressed:0 ql_uncompressed_size:29

注意观察上面输出字段 encoding 的值。quicklist是 ziplist和 linkedlist 的混合体,它将 linkedlist 按段切分,每一段使用 ziplist 让存储紧凑,多个 ziplist 之间使用双向指针串接起来,如图 5-9 所示。

image

struct ziplist{
	...
}

struct ziplist_compressed{
	int32 size;
	byte[] compressed_data;
}

struct quicklistNode{
	quicklistNode* prev;
	quicklistNode* next;
	ziplist* zl;//指向压缩列表
	int32 size;//ziplist 的字节总数
	int16 count;//ziplist 中的元素数量
	int2 encoding;//存储形式 2bit,原生字节数组还是 LZF 压缩存储
	...
}

struct quicklist{
	quicklistNode* head;
	quicklistNode* tail;
	long count;//元素总数
	int nodes;//ziplist节点的个数
	int compressDepth;//LZF算法压缩深度
	...
}

上述代码简单地表示了 quicklist 的大致结构。为了进一步节约空间,Redis 还会对 ziplist 进行压缩存储,使用 LZF 算法压缩,可以选择压缩深度。

每个 ziplist 存多少元素

quicklist 内部默认单个 ziplist 长度为 8KB,超出了这个字节数,就会另起一个ziplist。ziplist的长度由配置参数 list-max-ziplist-size 决定。

# Lists are also encoded in a special way to save a lot of space.#The number ofentries allowed per internal list node can bespecified
赴as a fixed maximum size or a maximum number of elements.好FOra fixed maximum size,use 5 through -l meaning:5:maxsize:64KbC..notrecommended for normal workloads
一4:maXsize:32 Kb<--notrecommended
16 Kb多-3:maXsize:<--probably not recommended
朴-2:max size:8 Kb<--good
朴-1:max size:4KbgoodC一-
洛Positive numbersmeanstoretoexactly that number ofuP
elements
#per list node.
#The highest performing option is usually-2(8 Kb size)or -1(4Kb size)#but if your usecase is unique,adjust the settings as
necessary.
list-max-ziplist-size -2

压缩深度

quicklist 默认的压缩深度是 0 ,也就是不压缩。压缩的实际深度由配置参数 list-compress-depth 决定。为了支持快速的 push/pop 操作, quicklist 的首尾两个 ziplist不压缩,此时压缩深度就是1。如果压缩深度为2,就表示 quicklist 的首尾第一个ziplist以及首尾第二个ziplist都不压缩。如图 5-10 所示的情况,压缩深度是1

image

作者:Esofar

出处:https://www.cnblogs.com/DCFV/p/18300537

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Duancf  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示