【Redis】深入理解 Redis 常用数据类型源码及底层实现(5.详解List数据结构)
本文是深入理解 Redis 常用数据类型源码及底层实现系列的第5篇~前4篇可移步( ̄∇ ̄)/
【Redis】深入理解 Redis 常用数据类型源码及底层实现(1.结构与源码概述)-CSDN博客
【Redis】深入理解 Redis 常用数据类型源码及底层实现(2.版本区别+dictEntry & redisObject详解)-CSDN博客
【Redis】深入理解 Redis 常用数据类型源码及底层实现(3.详解String数据结构)-CSDN博客
【Redis】深入理解 Redis 常用数据类型源码及底层实现(4.详解Hash数据结构)_查看 hash-max-ziplist-entries 命令-CSDN博客
正文开始~
在Redis 3之前,List数据结构底层ziplist和linkedlist双向链表(当列表对象中元素的长度比较小或者数量比较少的时候,采用ziplist来存储(内存紧凑,访问效率高,但是更新效率低,当数据量较大时,可能导致大量的内存复制)当列表对像中元素的长度比较大或者数据数量比较多的时候会使用linkedlist(修改效率高,但是内存开销大,当节点较多时,会产生大量的内存碎片)。
后续综合了两者的优缺点,使用quicklist替换了ziplist和linkedlist双向链表。
虽然都是quicklist,但其实在Redis 6及其以前和Redis 7及其以后也存在较大的不同。简单一句话来理解就是:Redis 6的quicklist中装的是ziplist而Redis 7的quicklist中装的是listpack(看过上一篇介绍Hash得文章的朋友应该了解listpack就是用来替代ziplist的)
我们可以对比下来看,首先是相关的配置参数
先看下都有的list-compress-depth和list-max-ziplist-size
- list-compress-depth指的是压缩配置,表示一个quicklist两端不被压缩的节点个数(这里的节点是quicklist双向链表的节点,不是里面的ziplist/listpack)
-
- 取值含义:
-
-
- 0:默认值,表示都不压缩
- n:quicklist两端各有n个节点不被压缩(中间的都压缩,n=1/2/3……)
-
- list-max-ziplist-size指的是ziplist中的entry的配置
-
- 取值含义:
-
-
- 正值:表示按照数据项个数来限定每个quicklist节点上的ziplist的长度(例如取5的时候,表示每个quicklist节点的ziplist最多包含5个数据项)
- 负值:表示按照占用字节数来限定每个quicklist节点上的ziplist长度
-
-
-
-
- 取值含义(只能取-5/-4/-3/-2/-1五个值)
-
-
-
-
-
-
- -5:每个quicklist节点上的ziplist大小不能超过64Kb(1kb=1024 bytes,即64*1024 bytes)
- -4:每个quicklist节点上的ziplist大小不能超过32Kb(1kb=1024 bytes,即32*1024 bytes)
- -3:每个quicklist节点上的ziplist大小不能超过16Kb(1kb=1024 bytes,即16*1024 bytes)
- -2:默认值,每个quicklist节点上的ziplist大小不能超过8Kb(1kb=1024 bytes,即8*1024 bytes)
- -1:每个quicklist节点上的ziplist大小不能超过4Kb(1kb=1024 bytes,即4*1024 bytes)
-
-
-
而Redis 7多了一个参数list-max-listpack-size,这个参数的含义跟list-max-ziplist-size基本一致,不过指的不是ziplist中的entry,而是listpack中的entry的配置
- 取值含义:
-
- 正值:表示按照数据项个数来限定每个quicklist节点上的listpack的长度(例如取5的时候,表示每个quicklist节点的listpack最多包含5个数据项)
- 负值:表示按照占用字节数来限定每个quicklist节点上的ziplist长度
-
-
- 取值含义(只能取-5/-4/-3/-2/-1五个值)
-
-
-
-
- -5:每个quicklist节点上的listpack大小不能超过64Kb(1kb=1024 bytes,即64*1024 bytes)
- -4:每个quicklist节点上的listpack大小不能超过32Kb(1kb=1024 bytes,即32*1024 bytes)
- -3:每个quicklist节点上的listpack大小不能超过16Kb(1kb=1024 bytes,即16*1024 bytes)
- -2:默认值,每个quicklist节点上的listpack大小不能超过8Kb(1kb=1024 bytes,即8*1024 bytes)
- -1:每个quicklist节点上的listpack大小不能超过4Kb(1kb=1024 bytes,即4*1024 bytes)
-
-
看张比较形象的图
quicklist.h
在quicklist.h的源代码中,我们可以看到每个节点被封装成了quicklistNode对象
typedef struct quicklist {quicklistNode *head;quicklistNode *tail;unsigned long count; /* total count of all entries in all ziplists */unsigned long len; /* number of quicklistNodes */int fill : QL_FILL_BITS; /* fill factor for individual nodes */unsigned int compress : QL_COMP_BITS; /* depth of end nodes not to compress;0=off */unsigned int bookmark_count: QL_BM_BITS;quicklistBookmark bookmarks[];
} quicklist;
我们解释下关键参数:
- *head:指向双向列表表头的指针
- *tail:指向双向列表表尾的指针
- count:记录ziplist中存放的元素个数
- len:双向链表的长度(quicklistNode的数量)
- compress:压缩深度(默认0表示不压缩)
不知道有没有小伙伴觉得奇怪,这些参数都没见到ziplist,但是为什么count表示的是ziplist中存放的元素个数?
那是因为在每个quicklistNode对象中,装着一个ziplist
typedef struct quicklistNode {struct quicklistNode *prev;struct quicklistNode *next;unsigned char *zl;unsigned int sz; /* ziplist size in bytes */unsigned int count : 16; /* count of items in ziplist */unsigned int encoding : 2; /* RAW==1 or LZF==2 */unsigned int container : 2; /* NONE==1 or ZIPLIST==2 */unsigned int recompress : 1; /* was this node previous compressed? */unsigned int attempted_compress : 1; /* node can't compress; too small */unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;
我们解释下关键参数:
- *prev:指向前一个节点的指针
- *next:指向后一个节点的指针
- *zl:指向实际存储数据的ziplist
- sc:当前ziplist占用的字节数
- count:当前ziplist中存放的元素数(最大65536)
- encoding:表示采用的压缩算法(1:RAW、2:LZF)
结构图解
接下来我们看下当执行新增元素操作时,源码的底层代码逻辑
Redis 6和Redis 7pushGenericCommand()方法略有不同(其实主要就是listpack替代ziplist的区别)
搞定🎉~~~~
相关文章:

【Redis】深入理解 Redis 常用数据类型源码及底层实现(5.详解List数据结构)
本文是深入理解 Redis 常用数据类型源码及底层实现系列的第5篇~前4篇可移步( ̄∇ ̄)/ 【Redis】深入理解 Redis 常用数据类型源码及底层实现(1.结构与源码概述)-CSDN博客 【Redis】深入理解 Redis 常用数据类型源码及底…...

Vue+Flask电商后台管理系统
在这个项目中,我们将结合Vue.js前端框架和python后端框架Flask,打造一个功能强大、易于使用的电商后台管理系统 项目演示视频: VueFlask项目 目录 前端环境(Vue.js): 后端环境(python-Flask&…...
SpringBoot保姆级入门文档
目录 1、SpringBoot的优点 2、和Spring、SpringMVC的对比 3、Xml 和 JavaConfig 1、SpringBoot的优点 2、和Spring、SpringMVC的对比 3、Xml 和 JavaConfig Spring 使用 Xml 作为容器配置文件,在 3.0 以后加入了 JavaConfig,使用 java 类做配置文件使…...
Springboot同一台服务器部署多个项目,导致redis混淆,如何根据不同项目区分
在Spring Boot应用中,如果在同一台服务器上部署了多个项目,并且每个项目都使用Redis作为缓存或存储,为了避免Redis数据混淆,你需要确保各个项目在访问Redis时使用不同的数据库索引号、键前缀或者连接配置。 以下是一些区分不同项目Redis数据的方法: 使用不同数据库索引:…...

redis启动错误
错误: Creating Server TCP listening socket 127.0.0.1:6379: bind: No error redis-server.exe redis.windows.conf redis-cli.exe shutdown auth "yourpassword"...

单片机烧录方式 -- IAP、ISP和ICP
目录 背景 1 什么是ICP 2 什么是ISP 3 什么是IAP 4 总结 背景 对于51单片机,我们使用STC-ISP上位机软件通过串口进行程序的烧写;对于STM32系列单片机,我们既可以通过串口烧写程序,也能通过JLink或是STLink进行程序的烧写&am…...
数据结构(C语言版)01
//顺序存储 int main(){ int ans[5]{1,1,1,1,3};//定义并初始化 printf("%d",ans[4]); return 0; } //链式存储 Typdef struct Lnode{ElemType data;struct Lnode *next; }Londe,*LinKlist;Londe *L; L(LinkList)malloc(sizeof(Lnode)); A->nextB;B->nextC;…...
Node.js-文件读取输入
Node.js-文件读取输入 fs模块(操作文件的模块) 读取 fs.readFile(path[, options], callback);[]里面 是可选参数,表示以什么样的编码 格式读取path是路径callback表示读取完成后的回调函数 例子 fs.readFile (‘./files/11.txt…...

时隔一年的测评:gpt3.5发展到什么程度了?
名人说:一花独放不是春,百花齐放花满园。——《增广贤文》 作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、简要介绍1、chatgpt是什么?2、主要特点3、工作原理4、应用限制5、使…...

[RCTF2015]EasySQL1 题目分析与详解
一、题目介绍: 1、题目来源: BUUCTF网址 2、题目介绍: 拿到flag。 二、解题思路: 我们发现题目首页有登录和注册账号两个选项,我们首先尝试注册账号,尝试注册username为admin的账号,输入密码…...

开源的 Python 数据分析库Pandas 简介
阅读本文之前请参阅-----如何系统的自学python Pandas 是一个开源的 Python 数据分析库,它提供了高性能、易用的数据结构和数据分析工具。Pandas 特别适合处理表格数据,例如时间序列数据、异构数据等。以下是对 Pandas 的简明扼要的介绍,包括…...

LeetCode 2125.银行中的激光束数量
银行内部的防盗安全装置已经激活。给你一个下标从 0 开始的二进制字符串数组 bank ,表示银行的平面图,这是一个大小为 m x n 的二维矩阵。 bank[i] 表示第 i 行的设备分布,由若干 ‘0’ 和若干 ‘1’ 组成。‘0’ 表示单元格是空的࿰…...
【探索AI】Sora - 探索AI视频模型的无限可能
Sora - 探索AI视频模型的无限可能 随着人工智能技术的飞速发展,AI视频模型已成为科技领域的新热点。而在这个浪潮中,OpenAI推出的首个AI视频模型Sora,以其卓越的性能和前瞻性的技术,引领着AI视频领域的创新发展。让我们将一起探讨…...

NGINX的重写与反向代理机制解析
目录 引言 一、重写功能 (一)if指令 1.判断访问使用的协议 2.判断文件 (二)return指令 1.设置返回状态码 2.返回指定内容 3.指定URL (三)set指令 1.手动输入变量值 2.调用其它变量值为自定义变…...

JVM的深入理解
1、JVM(Java虚拟机):我们java编译时候,下通过把avac把.java文件转换成.class文件(字节码文件),之后我们通过jvm把字节码文件转换成对应的cpu能识别的机器指令(翻译官角色)…...

JavaWeb——007MYSQL(DQL多表设计)
# 数据库开发-MySQL 一级目录二级目录三级目录 1. 数据库操作-DQL1.1 介绍1.2 语法1.3 基本查询1.4 条件查询1.5 聚合函数1.6 分组查询1.7 排序查询1.8 分页查询1.9 案例1.9.1 案例一1.9.2 案例二 2. 多表设计2.1 一对多2.1.1 表设计2.1.2 外键约束 2.2 一对一2.3 多对多2.4 案…...
深度学习500问——Chapter01:数学基础
文章目录 前言 1.1 向量和矩阵 1.1.1 标量、向量、矩阵、张量之间的联系 1.1.2 张量与矩阵的区别 1.1.3 矩阵和向量相乘结果 1.1.4 向量和矩阵的范数归纳 1.1.5 如何判断一个矩阵为正定 1.2 导数和偏导数 1.2.1 导数偏导计算 1.2.2 导数和偏导数有什么区别 1.3 特征值和特征向量…...

day03_登录注销(前端接入登录,异常处理, 图片验证码,获取用户信息接口,退出功能)
文章目录 1. 前端接入登录1.1 修改前端代码1.2 跨域请求1.2.1 跨域请求简介1.2.2 COSR概述CORS简介CORS原理 1.2.3 CORS解决跨域 2. 异常处理2.1 提示空消息分析2.2 系统异常分类2.3 异常处理2.2.1 方案一2.2.2 方案二 3. 图片验证码3.1 图片验证码意义3.2 实现思路3.3 后端接口…...

k8s初始化报错 [ERROR CRI]: container runtime is not running: ......
一、环境参数 linux系统为centos7kubernetes版本为v1.28.2containerd版本为1.6.28 二、报错内容 执行初始化命令kubeadm init命令时报错,内容如下 error execution phase preflight: [preflight] Some fatal errors occurred:[ERROR CRI]: container runtime is…...
vscode windows 免密登录 powershell.sh
Linux 生成秘钥 ssh-keygenwindows powershell.sh $HOST_IP"zhang192.168.1.1" $PUBPATH"$HOME\.ssh\id_rsa.pub" $KEY(Get-Content "$PUBPATH" | Out-String); ssh "$HOST_IP" "mkdir -p ~/.ssh && chmod 700 ~/.ssh …...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...