Redis底层数据结构之快链表(QuickList)

article/2025/6/7 13:46:55

QuickList基本结构

        用一句话来说,QuickList是一个双端链表,每一个链表节点中存储的是ZipList,参照下面这张图可以更好地理解QuickList的结构组成:

        QuickList在Redis6.0中一共定义了6个结构体,分别为:

        quicklistNode:定义了一个链表节点,可以理解为QuickList中实际的Node。

        quicklistLZF:定义了储存压缩后ZipList的数据结构。

        quicklistBookmark:定义了一个可以追加在quicklist尾部的书签,只有在大量节点的多余内存使用量可以忽略不计的情况且确实需要分批迭代它们时才会使用。

        quicklist:定义了一个双向链表,可以理解为QuickList的实体。

        quicklistIter:定义了一个迭代器。

        quicklistEntry:定义了一层封装,对ZipList中的entry概念的封装。

        文章只对quicklist和quicklistNode两个重点部分进行详细讲解。

quicklist的定义:

typedef struct quicklist {quicklistNode *head;quicklistNode *tail;unsigned long count;unsigned long len;int fill : QL_FILL_BITS;unsigned int compress : QL_COMP_BITS;unsigned int bookmark_count: QL_BM_BITS;quicklistBookmark bookmarks[];
} quicklist;

        head字段:指向头结点(上一个节点)的指针。

        tail字段:指向尾节点(下一个节点)的指针。

        count字段:所有ZipList数据项个数的总和。

        len字段:QuickList中包含的Node个数。

        fill字段:存放对ZipList的大小设置,如list-max-ziplist-size参数的值,占16bit。具体规则为:

                当数值为负数时,代表以字节数限制单个ZipList的最大长度。

                -1~-5:不超过4kb~64kb。

                当数值为正数时,代表以entry数目限制单个ZipList的最大长度,指就是具体的数目。

        compress字段:存放对节点压缩深度的设置,如list-compress-depth参数的值,占16bit。具体规则为:

                0:表示不压缩,zl字段直接指向ZipList;

                1:表示QuickList的头尾节点不压缩,其余节点zl字段指向经过压缩后的quicklistLZF;

                以此类推,值最大为2^16。

quicklistNode的定义:

typedef struct quicklistNode {struct quicklistNode *prev;struct quicklistNode *next;unsigned char *zl;unsigned int sz;unsigned int count : 16;unsigned int encoding : 2;unsigned int container : 2;unsigned int recompress : 1;unsigned int attempted_compress : 1; unsigned int extra : 10;
} quicklistNode;

        prev字段:指向链表前一个节点的指针。

        next字段:指向链表后一个节点的指针。

        zl字段:表示数据指针。如果当前节点的数据没有压缩,那么它指向一个ZipList结构;否则,他指向一个QuickListLZF结构。

        sz字段:表示zl字段指向的ZipList结构的总大小(即使ZipList被压缩了,这个sz字段表示的仍然是压缩前ZipList的大小)。

        count字段:占用16bit(2Byte),表示ZipList中包含的数据项个数。

        encoding字段:表示ZipList是否被压缩,1表示没有被压缩,2表示使用了LZF进行压缩。

        container字段:预留字段。(本来的设计是用来表明一个QuickList节点下面是直接存数据,还是使用了ZipList来存数据,或者是使用其他的数据容器来存数据,但在目前的实现中这个值被固定为2,表示使用ZipList来存数据)。

        recompress字段:标志位,用于标记数据是否需要重新被压缩。当我们使用lindex这样的命令查看了某一项压缩数据时,需要把数据暂时解压,这个时候recompress字段就被标志位1。

        attempted_compress字段:这个值用于Redis的自动化测试程序。

        extra字段:其它扩展字段。 

为什么引入QuickList?

        我们从ZipList存在的三个问题来回答这个问题。

        (1)ZipList虽然节省了内存,但是申请内存必须是连续空间,如果内存占用比较多,申请内存效率很低时怎么办?

        答:对ZipList的长度和entry大小进行限制。

        (2)如果限制了ZipList的长度和entry的大小,那么在要存储大量数据时,超出了ZipList的最佳上限该怎么办?

        答:可以创建多个ZipList来分片存储大量数据。

        (3)一个比较大的数据在拆分后比较分散,不方便管理和查找,那么多个ZipList之间该如何建立联系?

        答:引入双向链表,将每一个ZipList作为节点进行存储即可将多个ZipList串起来。

        这样就很自然的将QuickList给引出来了,实际上,在Redis3.2之后就加入了QuickList数据结构。

QuickList小结

        看完上文之后,大家会发现QuickList数据结构其实是普通双向链表和ZipList结合的产物,实际上这是在实际存储和性能上对两者进行的一个均衡。QuickList以ZipList作为节点,解决了传统双向链表头尾指针占用内存比例较大的问题;同时控制ZipList的大小,解决了ZipList存储大数据时连续内存申请效率的问题。

        QuickList的重点内容就这些啦,大家有什么问题或者勘误可以在评论区留言,笔者看到都会回复的。


http://www.hkcw.cn/article/HKSkjaMYrC.shtml

相关文章

Mac查看MySQL版本的命令

通过 Homebrew 查看(如果是用 Homebrew 安装的) brew info mysql 会显示你安装的版本、路径等信息。 你的终端输出显示:你并没有安装 MySQL,只是查询了 brew 中的 MySQL 安装信息。我们一起来看下重点: &#x1f9fe…

Spring Boot 自动配置原理:从入门到精通

Spring Boot 的自动配置是其核心特性之一,它极大地简化了 Spring 应用的开发,让开发者可以专注于业务逻辑,而无需编写大量的配置代码。 本文将深入探讨 Spring Boot 自动配置的原理,帮助你理解其工作机制,并能灵活运用…

网络原理1

协议 在网络通信中,协议是非常重要的概念。协议是在网络通信过程中的约定。发送方和接收方需要提前商量好数据的格式,才能确保正确进行沟通。 应用层协议 应用层,对应着应用程序,是跟我们程序员打交道最多的一层。调用操作系统…

【JSON-to-Video】设置背景视频片断

欢迎来到JSON转视频系列教程。今天要教大家如何添加背景视频片断,在视频制作中,巧妙运用背景视频,能为作品增添独特魅力。下面就为大家详细讲解具体步骤。 JSON转视频教程,添加背景视频片断 设置bgVideo字段 {"bgVideo"…

工作服/反光衣检测算法AI智能分析网关V4安全作业风险预警方案:筑牢矿山/工地/工厂等多场景安全防线

一、方案背景​ 在工地、矿山、工厂等高危作业场景,反光衣是保障人员安全的必备装备。但传统人工巡查存在效率低、易疏漏等问题,难以实现实时监管。AI智能分析网关V4基于人工智能技术,可自动识别人员着装状态,精准定位未穿反光衣…

Java垃圾回收机制深度解析:从理论到实践的全方位指南

Java垃圾回收(GC)是Java虚拟机(JVM)的核心功能,它自动管理内存分配与回收,避免了C/C中常见的内存泄漏问题。本文将深入剖析Java垃圾回收的工作原理、算法实现、收集器类型及调优策略,助你全面掌握JVM内存管理的精髓。 一、垃圾回收基础概念 …

实验设计与分析(第6版,Montgomery著,傅珏生译) 第9章三水平和混合水平析因设计与分式析因设计9.5节思考题9.1 R语言解题

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著&#xff0c;傅珏生译) 第9章三水平和混合水平析因设计与分式析因设计9.5节思考题9.1 R语言解题。主要涉及方差分析。 YieldDesign <-expand.grid(A gl(3, 1, labels c("-", "0","…

Vue内置组件Teleport和Suspense

一. Vue内置组件Teleport 认识Teleport( teleport&#xff1a;允许我们把组件的模板渲染到特定的元素上) 1.1. 在组件化开发中&#xff0c;我们封装一个组件A&#xff0c;在另外一个组件B中使用 组件A中template的元素&#xff0c;会被挂载到组件B中template的某个位置&#xf…

冷雨泉教授团队:新型视觉驱动智能假肢手,拟人化抓握技术突破,助力截肢者重获生活自信

研究背景&#xff1a;日常生活中&#xff0c;健康人依靠手完成对物体的操作。对于手部截肢患者&#xff0c;手部的缺失导致他们难以有效地操作物体&#xff0c;进而影响正常的日常生活。拥有一个能够实现拟人地自然抓取多种日常物体的五指动力假手是手部截肢患者的夙愿&#xf…

Ansys Zemax | 手机镜头设计 - 第 4 部分:用 LS-DYNA 进行冲击性能分析

附件下载 联系工作人员获取附件 该系列文章将讨论智能手机镜头模组设计的挑战&#xff0c;从概念和设计到制造和结构变形分析。本文是四部分系列中的第四部分&#xff0c;它涵盖了相机镜头的显式动态模拟&#xff0c;以及对光学性能的影响。使用 Ansys Mechanical 和 LS - DY…

windows可视化粘贴使用剪贴板

复制 ctrl c可视化粘贴 win v选择要粘贴的内容

【QT】认识QT

文章目录 1. 认识Qt2. 创建QT项目3. 认识对象树4. 其它4.1 窗口坐标系4.2 快捷键 1. 认识Qt 什么是QT Qt 是⼀个跨平台的C图形用户界⾯应用程序框架。 它为应用程序开发者提供了建立艺术级图形界⾯所需的所有功能。它是完全⾯向对象的&#xff0c;很容易扩展。Qt为开发者提供…

OpenCV CUDA模块特征检测------角点检测的接口createMinEigenValCorner()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数创建一个 基于最小特征值&#xff08;Minimum Eigenvalue&#xff09;的角点响应计算对象&#xff0c;这是另一种经典的角点检测方法&…

Java高级 | (二十二)快速应用开发框架——Spring Boot

一、使用IDEA搭建SpringBoot项目 二、创建控制器类 1、先运行项目。 如果配置正常&#xff0c;ldea运行界面如下&#xff0c;表示启动正常。 2、创建控制器类 鼠标右击controller包&#xff0c;点击new->Java Class,在弹出的对话框中输入“HelloController”并按回车健&a…

Linux 安装 JDK

Linux中JDK安装 文件路径在root目录&#xff0c;请根据实际情况进行修改 1、上传并解压 tar -zxvf /root/jdk-8u333-linux-x64.tar.gz2、移动解压后的文件夹到/usr/local 目录下&#xff0c; mv /root/jdk1.8.0_333 /usr/local/此步骤可以不操作&#xff0c;但步骤3中的路径…

简简单单探讨下starter

前言 今天其实首先想跟大家探讨下&#xff1a;微服务架构&#xff0c;分业务线了&#xff0c;接入第三方服务、包啥的是否自己定义一个stater更好&#xff1f; 一、starter是什么&#xff1f; 在 Spring Boot 中&#xff0c;Starter 是一种特殊的依赖模块&#xff0c;用于快速…

字符编码全解析:ASCII、GBK、Unicode、UTF-8与ANSI

UTF - 8(全球字符能被唯一标识)、GBK、Unicode、ANSI 区别与关联 qwen模型分词器文件 1. ASCII(基础铺垫,理解编码起源) 作用:最早期为处理英文文本设计,是字符编码的基础,后演变成其他编码兼容的一部分 。范围:共 128 个字符(0 - 127),包含英文大小写字母、数字…

定时线程池失效问题引发的思考

最近在做的一个新功能&#xff0c;在结果探测的时候使用了定时线程池和普通线程池结合&#xff0c;定时线程池周期性创建子任务并往普通线程池提交任务。 问题&#xff1a; 在昨天测试老师发现&#xff0c;业务实际上已经成功了&#xff0c;但是页面还是一直显示进行中。 收到…

Win11/Win10 打不开 gpedit.msc 之 组策略编辑器安装

目前已整理两种方式&#xff0c;推荐使用第二种方式~ 方式1&#xff1a; 一般家庭版操作系统默认未安装 组策略编辑器&#xff0c; 只需要进行安装一下即可。 到文章结尾按照提示下载相关的bat文件&#xff0c; 下载后右键以管理员身份运行bat文件&#xff0c;&#xff08…

无人机甲烷检测技术革新:开启环境与能源安全监测新时代

市场需求激增&#xff0c;技术革新势在必行 随着全球气候变化加剧&#xff0c;甲烷作为第二大温室气体&#xff0c;其减排与监测成为国际社会关注焦点。据欧盟甲烷法规要求&#xff0c;2024 年起欧洲能源基础设施运营商需定期测量甲烷排放并消除泄漏。与此同时&#xff0c;极端…