Redis压缩列表

区分一下

3.2之前 Redis中的List有两种编码格式 一个是LINKEDLIST 一个是ZIPLIST 这个ZIPLIST就是压缩列表

3.2之后来了一个QUICKLIST QUICKLIST是ZIPLIST和LINKEDLIST的结合体 也就是说Redis中没有ZIPLIST和LINKEDLIST了 然后在Redis5.0引入了LISTPACK用来替换QUiCKLIST中的ZIPLIST在REDIS7.0后完全取代了ZIPLIST

我们有说到压缩列表是List的底层数据结构,压缩列表主要用做为底层数据结构提供紧凑型的数据存储方式,能节约内存(节省链表指针的开销),小数据量的时候遍历访问性能好(连续+缓存命中率友好)。数据量少的时候会用它 

什么情况是数据量小的呢

1.列表对象保存的所有字符串对象长度都小于64字节;

2.列表对象元素个数少于512个,注意,这是LIST的限制,而不是ZIPLIST的限制;

满足以上两点 就会用ZIPLIST编码

ZIPLIST结构

zlbytes:表示该ZIPLIST一共占了多少字节数,这个数字是包含zlbytes本身占据的字节的。(夺大!)

zltail:ZIPLIST 尾巴节点相对于ZIPLIST的开头(起始指针)偏移的字节数。通过这个字段可以快速定位到尾部节点,例如现在有一个ZIPLIST,zl指向它的开头,如果要获取tail尾巴节点,即ZIPLIST里的最后一个节点,可以zl + zltail的值,这样定位到它。如果没有尾节点,就定位到 zlend

zllen:表示有多少个数据节点,在本例中就有3个节点。

entry1~entry3:表示压缩列表数据节点。

zlend:一个特殊的entry节点,表示ZIPLIST的结束。

ZIPLIST节点结构

就是上面的entry1 entry2....

他里面有三个字段

prevlen:表示上一个节点的数据长度。

encoding:编码类型。编码类型里还包含了一个entry的长度信息,可用于正向遍历

entry-data:实际的数据。

prevlen:

通过这个字段可以定位上一个节点的起始地址(或者说开头)也就是就是p-prevlen 可以跳到前一个节点的开头位置,实现从后往前操作,所以压缩列表才可以从后往前遍历。如果前一节点的长度,也就是前一个ENTRY的大小,小于254字节,那么prevlen属性需要用1字节长的空间来保存这个长度值,255是特殊字符,被zlend使用了如果前一节点的长度大于等于254字节,那么prevlen属性需要用5字节长的空间来保存这个长度值注意5个字节中中第一个字节为11111110,也就是254,标志这是个5字节的prelen信息,剩下4字节来表示大小。(这也差太多了 看人家MYSQL里面的可变长度列 少了就1字节 长了就2字节)

encoding:

00pppppp  1字节 String类型,且字符串长度小于2へ6,即小于等于63

 01pppppplqqqqqqqq  2字节 String类型,长度小于2^14次方,即小于等于16383

10000000|qqqqqqqq|rrrrrrrr|ssssssss|tttttttt 5字节 String类型,长度小于2へ32次方

110000001 2个字节的 int16类型

110100001 4个字节的 int32类型

11111110     1个字节的 int64类型

费老劲了 别背 就记住前几位是标识类型 后几位标识长度 对于int类型只标识类型 长度不用标

ZIPLIST性能

查询数据总量

由于ZIPLIST的header定义了记录节点数量的字段zllen,所以通常是可以在O(1)时间复杂度直接返回的,但是呢 zllen是两个字节的 也就是说最多也就能存65534的长度 大于了就存不下了 就得遍历了

遍历去吧 大于65534的节点数 累死 所以他只是应用节点数少的时候

查询指定节点

在ZIPLIST中查询指定数据的节点,需要遍历这个压缩列表,平均时间复杂度是O(N)。

更新数据

ZIPLIST的更新就是增加、删除数据,ZIPLIST提供头尾增减的能力,但是操作平均时间复杂度是O(N),因为在头部增加一个节点会导致后面节点都往后移动,所以更新的平均时间复杂度,可以看作O(N)。其中要注意的是更新操作可能带来连锁更新。注意上面所说的增加节点导致后移,不是连锁更新。连锁更新是指这个后移,发生了不止一次,而是多次。比如增加一个头部新节点,后面依赖它的节点,需要prevlen字段记录它的大小,原本只用1字节记录,因为更新可能膨胀为5字节,然后这个entry的大小就也膨胀了。所以,当这个新数据插入导致的后移完成之后,还需要逐步迭代更新。这种现象就是连锁更新,时间复杂度是O(Nへ2),6.2已经优化为O(N),不用太过担心连锁更新的情况,实际的业务中,很少会刚好遇到需要迭代更新超过2个节点的情况,所以ZIPLIST更新平均时间复杂度,还是可以看作O(N)。不过,ZIPLIST最大的问题还是连锁更新导致性能不稳定。

LISTPACK优化

优化了连锁更新

LISTPACK是为了解决ZIPLIST最大的痛点——连锁更新,我们先来看,ZIPLIST的问题本源。我们知道,ZIPLIST需要支持LIST,LIST是一种双端访问结构,所以需要能从后往前遍历,上面有讲,ZIPLIST的数据节点的结构是这样的:

<prevlen> <encoding> <entry-data>

其中,prevlen就表示上一个节点的数据长度,通过这个字段可以定位上一个节点的数据,可以说,连锁更新问题,就是因为prevlen导致的。

所以我们需要一种不记录prevlen,并且还能找到上一个节点的起始位置的办法,Redis使用了很巧妙的一种方式。我们直接看LISTPACK的节点定义:

1 <encoding-type><element-data><element-tot-len>

encoding-type是编码类型

element-data是数据内容

element-tot-len存储整个节点除它自身之外的长度。

element-tot-len 所占用的每个字节的第一个bit用于标识是否结束。0是结束,1是继续,剩下7个bit来存储数据大小。当我们需要找到当前元素的上一个元素时,我们可以从后向前依次查找每个字节,找到上一个Entry的element-tot-len 字段的结束标识,就可以算出上一个节点的首位置了。举个例子:如果上个节点的element-tot-len为00000001 10000100,每个字节第一个bit标志是否结束,所以这里的element-tot-len一共就两个字节,大小为00000010000100,即132字节。

一些QS

1.ZIPLIST有什么优点

首先肯定是相对于LINKEDLIST

1.节约内存,内存利用率高 2.方便一次性分配 3.遍历时局部性更强

2.ZIPLIST是怎么压缩数据的?

就是看它的结构

然后entry的结构是

他里面的这个entry是紧密相连的 

 3.ZIPLIST下List可以从后往前和从前往后遍历吗

可以 它是双端队列结构 从结构分析 它里面有个encoding结构 包含了长度信息 实现了正向遍历

prelen上一个节点的长度 实现了反向遍历

4.压缩列表插入的时间复杂度是多少?

头部插入是O(N)  他要把后面的数据往后挤  尾部插入O(1)

5.连锁更新的原因如何解决

就跟多米诺骨牌似的 如果上一个节点小于254字节 那下一个节点的prevlen是1长度 要是正好处于这个阈值 更新到了255 那下一个节点就得提升4个字节 那下一个节点也可能提升 balabla

解决就是别保存上一个节点长度 LISTPACK记录的当前节点的长度

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/78360.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue整合脑图编辑管理系统-kitymind百度脑图

前言 项目为前端vue项目&#xff0c;把kitymind百度脑图整合到前端vue项目中&#xff0c;显示了脑图的绘制&#xff0c;编辑&#xff0c;到处为json&#xff0c;png&#xff0c;text等格式的功能 文章末尾有相关的代码链接&#xff0c;代码只包含前端项目&#xff0c;在原始的…

线性代数 | 机器学习数学基础

前言 线性代数&#xff08;linear algebra&#xff09;是关于向量空间和线性映射的一个数学分支。它包括对线、面和子空间的研究&#xff0c;同时也涉及到所有的向量空间的一般性质。 本文主要介绍机器学习中所用到的线性代数核心基础概念&#xff0c;供读者学习阶段查漏补缺…

Visual Studio 2022的MFC框架——应用程序向导

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来重新审视一下Visual Studio 2022开发工具下的MFC框架知识。 MFC(Microsoft Foundation Class&#xff0c;微软基础类库&#xff09;是微软为了简化程序员的开发工作所开发的一套C类的集合&#xf…

roop 视频换脸

roop: one click face swap. 只用一张人脸图片&#xff0c;就能完成视频换脸。 项目地址&#xff1a; https://github.com/s0md3v/roopColab 部署&#xff1a; https://github.com/dream80/roop_colab 本文是本地部署的实践记录。 环境基础 OS: Ubuntu 22.04.2 LTSKernel: 5…

GPIO实验

一、GPIO GPIO&#xff08;General-purpose input/output&#xff09;即通用型输入输出&#xff0c;GPIO可以控制连接在其之上的引脚实现信号的输入和输出 芯片的引脚与外部设备相连&#xff0c;从而实现与外部硬件设备的通讯、控制及信号采集等功能 LED实验步骤 最终目的&am…

2020-2023中国高等级自动驾驶产业发展趋势研究

1.1 概念界定 2020-2023中国高等级自动驾驶产业发展趋势研究Trends in China High-level Autonomous Driving from 2020 to 2023自动驾驶发展过程中&#xff0c;中国出现了诸多专注于研发L3级以上自动驾驶的公司&#xff0c;其在业界地位也越来越重要。本报告围绕“高等级自动…

vue2-diff算法

1、diff算法是什么&#xff1f; diff算法是一种通过同层的树节点进行比较的高效算法。 其有两个特点&#xff1a; 比较只会在同层级进行&#xff0c;不会跨层级进行。 在diff比较的过程中&#xff0c;循环从两边向中间比较。 diff算法在很多场景中都有应用&#xff0c;在vue中&…

mac电脑访问windows共享文件夹连接不上(设置445端口)

前提&#xff1a;首先需要保证mac和windows都在同一局域网内&#xff0c;如果不在肯定是连不上的&#xff0c;就不用往下看了。 事情是这样的&#xff0c;公司入职发了mac电脑&#xff0c;但是我是window重度用户&#xff0c;在折腾mac的过程中&#xff0c;有许多文件需要从wi…

【Jenkins】Jenkins 安装

Jenkins 安装 文章目录 Jenkins 安装一、安装JDK二、安装jenkins三、访问 Jenkins 初始化页面 Jenkins官网地址&#xff1a;https://www.jenkins.io/zh/download/ JDK下载地址&#xff1a;https://www.oracle.com/java/technologies/downloads/ 清华源下载RPM包地址&#xff…

vim、awk、tail、grep的使用

vim命令 $定位到光标所在行的行末^定位到光标所在行的行首gg定位到文件的首行G定位到文件的末行dd删除光标所在行ndd删除n行&#xff08;从光标所在行开始&#xff09;D删除光标所在行&#xff0c;使之变为空白行x删除光标所在位置字符nx删除n个字符&#xff0c;从光标开始向后…

使用Python将Word文档转换为PDF的方法

摘要&#xff1a; 文介绍了如何使用Python编程语言将Word文档转换为PDF格式的方法。我们将使用python-docx和pywin32库来实现这个功能&#xff0c;这些库提供了与Microsoft Word应用程序的交互能力。 正文&#xff1a; 在现实生活和工作中&#xff0c;我们可能会遇到将Word文…

召唤神龙打造自己的ChatGPT

在之前的两篇文章中&#xff0c;我介绍了GPT 1和2的模型&#xff0c;并分别用Tensorflow和Pytorch来实现了模型的训练。具体可以见以下文章链接&#xff1a; 1. 基于Tensorflow来重现GPT v1模型_gzroy的博客-CSDN博客 2. 花费7元训练自己的GPT 2模型_gzroy的博客-CSDN博客 有…

揭秘女程序员找男友的首选职业,你猜是哪个?

大家好&#xff0c;这里是程序员晚枫。 大家有没有发现&#xff1a;身边单身的男程序员很多&#xff0c;而单身的女程序员更多&#xff1f; 今天我们就来一起讨论一下&#xff0c;女程序员适合什么职业的男生&#xff1f;01 推荐 女程序员适合什么职业的男生&#xff0c;这…

一篇文章教会你一个优秀的程序员如何维护好自己的电脑

程序员如何维护好自己的电脑 1. 程序员的电脑种类都有哪些2. 硬件如何维护2.1 开关机问题2.2 Windows更新问题2.3 笔记本充电和电池问题2.4 笔记本清灰问题 3. 系统及软件维护3.1 杀毒软件和垃圾清理问题3.2 磁盘分盘问题3.3 浏览器和搜索引擎的选择3.4 系统备份和PE盘的使用 总…

ELK、ELFK日志分析系统

菜单一、ELK简介1.1 ELK组件说明1.1.1 ElasticSearch1.1.2 Kiabana1.1.3 Logstash 1.2 可以添加的其它组件1.2.1 Filebeat1.2.2 缓存/消息队列&#xff08;redis、kafka、RabbitMQ等&#xff09;1.2.3 Fluentd 1.3 为什么要用ELK1.4 完整日志系统的基本特征1.5 ELK 的工作原理 …

2023年华数杯数学建模A题思路代码分析 - 隔热材料的结构优化控制研究

# 1 赛题 A 题 隔热材料的结构优化控制研究 新型隔热材料 A 具有优良的隔热特性&#xff0c;在航天、军工、石化、建筑、交通等 高科技领域中有着广泛的应用。 目前&#xff0c;由单根隔热材料 A 纤维编织成的织物&#xff0c;其热导率可以直接测出&#xff1b;但是 单根隔热…

Selenium自动化测试总结

一、Selenium自动化测试&#xff08;基于python&#xff09; 1、Selenium简介&#xff1a; 1.1 Selenium是一款主要用于Web应用程序自动化测试的工具集合。Selenium测试直接运行在浏览器中&#xff0c;本质是通过驱动浏览器&#xff0c;模拟浏览器的操作&#xff0c;比如跳转、…

Springboot+Easyexcel将数据写入模板文件并导出Excel

SpringbootEasyexcel将数据写入模板文件并导出Excel 一、导入依赖二、根据excel表头创建对应的实体类Pojo三、Controller类接收请求四、Service层获取待写入数据五、效果展示六、总结 一、导入依赖 <!--操作excel工具包--> <dependency><groupId>com.alibab…

Spring 事务详解(注解方式)

目 录 序言 1、编程式事务 2、配置声明式事务 2.1 基于TransactionProxyFactoryBean的方式&#xff08;不常用&#xff0c;因为要为每一个类配置TransactionProxyFactoryBean&#xff09; 2.2 基于AspectJ的XML方式&#xff08;常用&#xff0c;可配置在某些类下的所有子…

Kubernetes 整体架构介绍

架构图 Kubernetes 主要由以下几个核心组件组成&#xff1a; etcd 保存了整个集群的状态&#xff1b;kube-apiserver 提供了资源操作的唯一入口&#xff0c;并提供认证、授权、访问控制、API 注册和发现等机制&#xff1b;kube-controller-manager 负责维护集群的状态&#xf…