Redis底层数据结构之quicklist

redis底层数据结构已完结👏👏👏:

一、概述

QuickList是由多个 ziplist 组成的双向链表,每个 ziplist 存储一定数量的元素。优点:结合了 ziplist 和双向链表的优点,既节省空间,又提升了修改操作的性能。使用场景: 在列表键元素较多或包含较大元素时使用。

在这里插入图片描述

ziplist补充(ziplist缺点-链式扩容&级联更新)
当一个entry被插入的时候,我们需要设置下一个entry中的prevlen字段为新插入entry的长度。会发生如下的情况:新插入entry的长度超过了254[>=254],那么下一个entry的prelen需要5个字节记录该长度,但是呢,此时下一个entry的prevlen字段此时只有一个字节,所以需要对下一个entry进行grown[扩容],更糟糕的是,下个entry因为扩容导致长度超过254,还会引起下下个entry的扩容…,这种现象呢就是级联更新,简单点来说就是,因为一个entry的插入导致之后的entry都需要重新扩容和记录前一个entry的prevlen现象称之为“级联更新”

从 Redis 6.2 版本开始,quicklist 的底层实现由原来的 ziplist 改为了 listpack。Listpack 是 ziplist 的升级版本,主要是为了解决ziplist中存在的一些问题,比如,ziplist中扩展元素长度时可能需要进行昂贵的重新分配操作。listpack 提供了更好的性能和内存使用效率,在保持与 ziplist 类似的密集存储方式的同时,允许更大的单个元素大小,并且有更强的扩展性。listpack和ziplist对象结构的不同是,listpack将prevlen替换为了curlen,从而有效避免级联更新。并将且将culen字段放在entry结构的最后面。这样做是为了,能够通过total-bytes定位到最后一个element的末尾位置然后获取到curlen从而找到前一个element的位置,从而实现从后往前遍历。

补充说明listpack和ziplist
参考博客 ziplist和listpack

  • ziplist包括三大部分,<头部,entry,尾部>。头部包含"zlbytes,zltail,zllen";尾部包含"zlend标记ziplist的结尾";entry包括"prevlen,encoding,entry_data"。由于prevlen记录方式存在级联更新的问题,小于254字节需要1字节内存,大于等于254字节需要5字节内存。
  • listpack包括三大部分,<头部,entry,尾部>
### Redis 列表的底层数据结构 Redis列表采用快速链表(quicklist)作为其底层数据结构[^2]。这种设计融合了双向链表与压缩列表(ziplist)的优点。 #### 快速链表 (QuickList) 快速链表本质上是一种优化后的双向链表,其中每个节点不仅指向前后相邻的节点,还包含了一个压缩列表 ziplist。这意味着每一个 quicklist 节点实际上封装了一个小型的 ziplist 结构,从而允许更高效的内存管理和访问模式[^3]。 ```c typedef struct quicklist { // ...其他成员... quicklistNode *head; quicklistNode *tail; } quicklist; typedef struct quicklistNode { unsigned char encoding; /* 编码方式 */ int count; /* 当前ziplist中的元素数量 */ int mem_usage; /* 使用了多少字节 */ quicklistEntry entry; /* 用于迭代器 */ struct quicklistNode *prev, *next;/* 前驱和后继指针*/ unsigned char *zl; /* 指向ziplist的实际数据 */ } quicklistNode; ``` #### ZIPLIST 特性 Ziplist 是一种紧凑型线性序列化容器,在单个连续分配的缓冲区内存储一系列项。它特别适合于短字符串或小整数值,并能显著减少内存碎片并提高缓存命中率。然而,随着长度增加,操作效率可能会受到影响;因此,当达到一定阈值时,系统会选择切换至更为传统但占用更多空间的实现方法[^1]。 #### API 和自动调整机制 为了简化开发者的工作流程,Redis 提供了一系列高级别的命令接口来处理列表的操作,比如 LPUSH、RPUSH 等等。这些API能够透明地管理内部使用的具体数据结构形式——无论是初始状态下的ziplist还是扩展之后形成的完整双向链表形态。此外,根据实际应用场景的需求变化,Redis 还可以在运行期间动态改变所选用的数据结构类型以保持最佳性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值