探秘 Redis 快速列表

快速列表(quicklist )是列表(list)的底层实现之一,当列表中元素较少,并且里面的字符串的长度不长时,Redis 使用的压缩列表(ziplist)来存储的,这个大家都知道了哈,然而当列表中的元素越来越多,或者某一个元素的长度太大时就会使用快速列表来存储元素了。

这里需要说明的一点是 Redis 早期版本存储列表数据结构使用的是压缩列表 ziplist 和普通的双向链表linkedlist,也就是元素少时用 ziplist,元素多时用 linkedlist,但是这种存储结构,每个节点里面光是两个指向前一个节点的 prev 指针和一个指向后一个节点的 next 指针就要占据大量的空间,而且每个节点的内存都是单独分配的,加剧了内存的碎片化,为了尽可能节约内存,在 Redis 的后续版本中(3.2版本后)对列表进行了改造,采用快速列表代替了普通双向列表。

quicklist 是 ziplist 和 linkedlist 的混合体,它将 linkedlist 按段切分,每一段使用 ziplist 来紧凑存储,多个 ziplist 之间使用双向指针串接起来。
在这里插入图片描述
quicklistNode 定义:

struct quicklistNode {
	quicklistNode* prev;
 	quicklistNode* next;
 	ziplist* zl; 
 	int32 size; 
 	int16 count; 
 	int2 encoding;
}

prev 指向前一个节点的指针
next 指向后一个节点的指针
zl 指向压缩列表
size 表示ziplist 的字节总数
count 表示ziplist 中的元素数量
encoding 表示存储形式,原生字节数组还是 LZF 压缩存储

quicklist 定义:

struct quicklist {
 quicklistNode* head;
 quicklistNode* tail;
 long count; 
 int nodes; 
 int compressDepth; 
}

count 表示元素总数
nodes 表示ziplist 节点的个数
compressDepth 表示LZF 算法压缩深度

quicklist 中的单个ziplist默认长度为 8k 字节,超出了这个字节数,就会新起一个ziplist。

ziplist 的长度由配置参数 list-max-ziplist-size 决定。

压缩

为了进一步节约空间,Redis 还会对 ziplist 使用 LZF 算法进行压缩存储,我们可以配置压缩实际深度,压缩的实际深度由配置参数 listcompress-depth 决定。

quicklist 默认的压缩深度是 0,也就是不压缩。为了支持快速的push/pop 操作,quicklist 的首尾两个 ziplist 不压缩,此时深度就是 1。如果深度为 2,就表示 quicklist 的首尾第一个 ziplist 以及首尾第二个 ziplist 都不压缩。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值