当前位置: 首页
业界动态
我把 Redis 最复杂的数据结构拆开来了:quicklist,一个藏着三层设计哲学的「链表」

我把 Redis 最复杂的数据结构拆开来了:quicklist,一个藏着三层设计哲学的「链表」

热心网友 时间:2026-04-22
转载

一、从一个「翻车」的设计说起

如果回顾Redis的早期版本,你会发现List类型的底层实现,确实是经典的双向链表(adlist)。这种结构逻辑清晰明了:每个节点独立分配内存,通过prev和next指针像珍珠项链一样串起来。

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

但是,这种优雅背后藏着一个“内存杀手”:极度的内存碎片化。你可以想象一下,存放一大堆小数据时,情况会变得多么尴尬。

双向链表的内存现实: [节点A]──→[节点B]──→[节点C]──→[节点D] ↑ ↑ ↑ ↑ 堆上某处 堆上某处 堆上某处 堆上某处 每个节点:prev指针(8B) + next指针(8B) + value指针(8B) + 实际数据 存1000个小字符串,光指针开销就是 1000 × 24 = 24000 字节 实际数据可能才几千字节,指针比数据还多

于是,为了解决指针开销过大的问题,ziplist被引入了。它的思路很直接:把所有元素都紧凑地塞进一块连续内存里,彻底告别指针。内存利用率是上去了,但新的麻烦随之而来:任何插入或删除操作,都可能引发整块内存的重新分配。更致命的是,还存在“连锁更新”的风险——一旦触发,性能就可能断崖式下跌。

你看,两种结构各有利弊,也各有“死xue”。不过,Redis的工程师们没有简单地二选一,而是走了第三条路:取长补短,把两者的优点结合起来,让缺点相互对冲。这个智慧的结晶,就是quicklist。

二、quicklist是什么?一句话说清楚

如果用最简洁的公式来概括,那就是:quicklist = 双向链表 × listpack

怎么理解呢?它不再让链表的每个节点只存放单个元素,而是让每个节点承载一个小型的紧凑数组,也就是listpack。一个listpack里可以存放多个元素。

quicklist 整体结构: head tail ↓ ↓ [node1] ←──→ [node2] ←──→ [node3] ←──→ [node4] ↓ ↓ ↓ ↓ [lp: e1,e2,e3] [lp: e4,e5] [lp: e6,e7,e8] [lp: e9,e10] 每个 node 内部是一个 listpack(连续内存块) 多个 node 通过双向链表串联

这种设计的精妙之处立刻显现出来:

  • 得益于listpack内部的紧凑存储,指针开销被彻底消除,内存利用率大幅提升。
  • 链表节点的总数显著减少,使得维持链表结构所需的prev/next指针开销被大幅稀释。
  • 每个listpack的体量都受到控制,因此即便发生内存重分配,代价也有限,完全避免了全量数据迁移的风险。

可以说是一举三得。

三、还不够:quicklist再加一层压缩

然而,仅仅是“链表套listpack”的组合拳,Redis的工程师们觉得还不够极致。他们又在quicklist之上,加入了第三层设计:LZF压缩

这个思路非常贴合实际场景:在一个很长的列表中,两端的元素(比如进行lpush、rpop操作时)访问频率最高,而中间一大段元素可能长时间处于“冷板凳”状态。既然这些中间节点不怎么被访问,何不把它们压缩起来,进一步节省内存呢?

compress depth = 2 时的内存状态: [node1] [node2] | [node3] [node4] ... [nodeN-3] [nodeN-2] | [nodeN-1] [nodeN] 不压缩 不压缩 | 压缩 压缩 压缩 压缩 | 不压缩 不压缩 ←── 热区 ──────→|←──────────── 冷区(LZF压缩) ──────────→|←─── 热区 ──────→

参数“compress depth”就决定了链表两端各有几个节点保持原样(不压缩),而中间的所有节点则用LZF算法压缩存储。当需要访问中间某个节点时,系统会实时解压,用完后可能再重新压缩回去。这种用“计算换空间”的策略,在内存敏感的场景下非常有效。

至此,quicklist的三层架构清晰地展现在我们面前:最外层是双向链表结构,中层是listpack提供的紧凑存储,内层则是LZF针对冷数据的动态压缩。每一层都精准地解决了上一层次留下的问题,环环相扣,堪称工程权衡的典范。

四、还有一个让人琢磨的细节:节点分裂

在研究quicklist源码时,有一个操作起初让我有些费解,那就是 _quicklistSplitNode——节点分裂。究竟在什么情况下需要分裂一个节点呢?

想象这样一个场景:你试图在一个listpack的中间位置插入一个新元素,但这个listpack已经“满员”了(达到了fill参数设定的容量上限)。此时,唯一的办法就是把这个已经满载的listpack节点“一分为二”。

分裂前: [node]: [e1][e2][e3][e4][e5] ← listpack已满,要在e3后面插入新元素 分裂过程: step1: 以 e3 为界,创建左节点 [e1][e2][e3] step2: 创建右节点 [e4][e5] step3: 原节点从链表中移除 step4: 左右节点插入链表 step5: 在左节点尾部 或 右节点头部 插入新元素 分裂后: [node_left]: [e1][e2][e3][new] ←──→ [node_right]: [e4][e5]

然而,分裂操作会带来一个新的问题:链表中可能出现大量只包含寥寥数个元素的小节点,这显然不够经济。因此,Redis在分裂之后,通常还会紧接着尝试执行相邻小节点的合并操作(_quicklistMergeNodes)。分裂是为了给新元素腾出空间,合并则是为了整理内存、提高效率。这一分一合,共同构成了quicklist节点管理的完整逻辑。

五、listpack:被低估的主角

在讨论quicklist时,listpack常常被当作一个附属品被轻描淡写地略过。但这其实低估了它的价值。作为Redis 7.x中正式取代ziplist的新一代紧凑数据结构,listpack解决了一个长期存在的核心痛点——连锁更新问题。

listpack 内存布局: total_bytes(4B) num_elements(2B) entry...entry end(1B=0xFF) ─────────────────────────────────────────────────────────────── │ 总字节数 │ 元素个数 │ 各元素编码 │ 结束标志 │ ─────────────────────────────────────────────────────────────── 每个 entry 的结构: encoding + data + backlen 其中 backlen 记录当前 entry 的总长度 → 向前遍历时只需读 backlen,不依赖前驱节点长度 → 彻底消灭了 ziplist 的连锁更新

listpack的关键创新在于,每个entry都在尾部自带一个记录自身长度的字段(backlen)。这意味着当需要向前遍历时,只需读取本entry的backlen就能定位到前一个entry的起始位置,完全不需要知道前一个entry的具体长度。正是这个看似微小的改变,从根本上斩断了连锁更新的传递链条。这不仅仅是一次优化,更是对一个经典工程缺陷的根本性修复。

来源:https://www.51cto.com/article/838152.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
什么是RPA?为什么用RPA?RPA如何工作?

什么是RPA?为什么用RPA?RPA如何工作?

什么是RPA 简单来说,RPA是一种在商业逻辑与规则控制下,用来精简和优化流程的自动化系统。我们常把它比作一位不知疲倦的“数字员工”,专门用来高效处理那些重复性强、规则明确的任务。想一想后台办公室的场景:许多具备平均知识水平的员工,每天不得不花费大量时间在冗长、乏味且令人厌倦的例行程序上。RPA工具

时间:2026-04-22 22:40
不破不立,让RPA像Excel一样方便易用

不破不立,让RPA像Excel一样方便易用

RPA:从“专家可用”到“人人可用”,一道亟待跨越的鸿沟 提到RPA(机器人流程自动化),很多人的第一印象是“非侵入式”和“高效”。确实,这项技术能在不改造原有系统的前提下,为企业实现流程自动化,单凭这一点就赢得了大量青睐。但它的魅力远不止于此。 它的可扩展性和灵活性,让它能够适配千行百业的数字化转

时间:2026-04-22 22:40
RPA技术在营销业务中的应用案例

RPA技术在营销业务中的应用案例

RPA技术在营销业务中的应用案例 (1)智能停电全流程机器人 公变用户的停电流程,过去是个典型的“磨人”活。每天要重复登录好几个系统,处理异常派单,还得不停地和现场人员电话沟通,手动核对、搜索各种信息。这一套组合拳打下来,不仅耗费大量人力,更头疼的是,一旦遇到人员流动或者手一抖出了操作误差,公变停电

时间:2026-04-22 22:40
RPA技术的概念、优势和技术架构

RPA技术的概念、优势和技术架构

概念 说起机器人流程自动化(RPA),它其实是一种利用“软件机器人”来代劳那些高度重复性工作的技术。简单理解,它就是在你电脑里运行的一个程序,或者说一个虚拟的“数字员工”。它的核心任务,就是模拟人类与计算机的交互方式,把那些繁琐、复杂又量大的事务性工作承接过来,从而在降低人力成本的同时,大幅提升整体

时间:2026-04-22 22:39
基于RPA的财务共享服务中心资金管理系统框架

基于RPA的财务共享服务中心资金管理系统框架

(一)RPA是什么 RPA,也就是机器人流程自动化,是近年来在人工智能浪潮下兴起的一门自动化技术。简单说,它就像一个不知疲倦的“数字员工”,能够通过预设好的程序,模拟并执行我们人类在电脑上的各种操作。无论是登录系统、复制粘贴数据,还是核对报表,它都能一丝不苟地完成。 它的优势非常突出:可以按照设定7

时间:2026-04-22 22:39
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜
热门教程
更多
  • 游戏攻略
  • 安卓教程
  • 苹果教程
  • 电脑教程