redis的紧凑列表ziplist、quicklist、listpack

news2024/9/22 21:14:17

文章目录

  • 前言
  • 一、ziplist
    • 1.1 ziplist 查找复杂度高
    • 1.2 ziplist 连续更新风险
  • 二、quicklist
  • 三、listpack


前言

当数据量较小时,Redis 会优先考虑用 ziplist 来存储 hash、list、zset,这么做可以有效的节省内存空间,因为 ziplist 是一块连续的内存空间,它采用一种紧凑的方式来存储元素。但是它也有缺点,比如查找的时间复杂度高、内存分配的开销、连锁更新的风险等。
于是 Redis 在 3.0 版本推出了 quicklist,它可以看作是 ziplist 的升级版,本质是把多个 ziplist 串联成链表,把每个 ziplist 限制在一定的大小,以此来降低 内存分配、连锁更新 的影响,但是它并没有完全解决连锁更新的问题,并且链表的每个节点也是要额外占用内存的。
Redis 5.0 终于推出了一个新的紧凑列表 listpack,它沿用了 ziplist 的内存布局,元素紧挨在一起,没有指针的额外开销,同时解决了连锁更新的问题。


一、ziplist

一个 ziplist 数据结构在内存中的布局,就是一块连续的内存空间。这块空间的起始部分是大小固定的 10 字节元数据,其中记录了 ziplist 的总字节数、最后一个元素的偏移量以及列表元素的数量,而这 10 字节后面的内存空间则保存了实际的列表数据。在 ziplist 的最后部分,是一个 1 字节的标识(固定为 255),用来表示 ziplist 的结束,如下图所示:

在这里插入图片描述
不过,虽然 ziplist 通过紧凑的内存布局来保存数据,节省了内存空间,但是 ziplist 也面临着随之而来的两个不足:查找复杂度高和潜在的连锁更新风险。那么下面,我们就分别来了解下这两个问题。

1.1 ziplist 查找复杂度高

因为 ziplist 头尾元数据的大小是固定的,并且在 ziplist 头部记录了最后一个元素的位置,所以,当在 ziplist 中查找第一个或最后一个元素的时候,就可以很快找到。

但问题是,当要查找列表中间的元素时,ziplist 就得从列表头或列表尾遍历才行。而当 ziplist 保存的元素过多时,查找中间数据的复杂度就增加了。更糟糕的是,如果 ziplist 里面保存的是字符串,ziplist 在查找某个元素时,还需要逐一判断元素的每个字符,这样又进一步增加了复杂度。

也正因为如此,我们在使用 ziplist 保存 Hash 或 Sorted Set 数据时,都会在 redis.conf 文件中,通过 hash-max-ziplist-entries 和 zset-max-ziplist-entries 两个参数,来控制保存在 ziplist 中的元素个数。

不仅如此,除了查找复杂度高以外,ziplist 在插入元素时,如果内存空间不够了,ziplist 还需要重新分配一块连续的内存空间,而这还会进一步引发连锁更新的问题。

1.2 ziplist 连续更新风险

举个简单的例子,当在一个元素 A 前插入一个新的元素 B 时,A 的 prevlen 和 prevlensize 都要根据 B 的长度进行相应的变化。那么现在,我们假设 A 的 prevlen 原本只占用 1 字节(也就是 prevlensize 等于 1),而能记录的前一项长度最大为 253 字节。此时,如果 B 的长度超过了 253 字节,A 的 prevlen 就需要使用 5 个字节来记录,这样就需要申请额外的 4 字节空间了。不过,如果元素 B 的插入位置是列表末尾,那么插入元素 B 时,我们就不用考虑后面元素的 prevlen 了。
在这里插入图片描述
实际上,所谓的连锁更新,就是指当一个元素插入后,会引起当前位置元素新增 prevlensize 的空间。而当前位置元素的空间增加后,又会进一步引起该元素的后续元素,其 prevlensize 所需空间的增加。

这样,一旦插入位置后续的所有元素,都会因为前序元素的 prevlenszie 增加,而引起自身空间也要增加,这种每个元素的空间都需要增加的现象,就是连锁更新。如下图:
在这里插入图片描述
连锁更新一旦发生,就会导致 ziplist 占用的内存空间要多次重新分配,这就会直接影响到 ziplist 的访问性能。所以说,虽然 ziplist 紧凑型的内存布局能节省内存开销,但是如果保存的元素数量增加了,或是元素变大了,ziplist 就会面临性能问题。那么,有没有什么方法可以避免 ziplist 的问题呢?这就是接下来我要给你介绍的 quicklist 和 listpack,这两种数据结构的设计思想了。

二、quicklist

quicklist 的设计,其实是结合了链表和 ziplist 各自的优势。简单来说,一个 quicklist 就是一个链表,而链表中的每个元素又是一个 ziplist。
在这里插入图片描述
而也正因为 quicklist 采用了链表结构,所以当插入一个新的元素时,quicklist 首先就会检查插入位置的 ziplist 是否能容纳该元素,这是通过 _quicklistNodeAllowInsert 函数来完成判断的。

_quicklistNodeAllowInsert 函数会计算新插入元素后的大小(new_sz),这个大小等于 quicklistNode 的当前大小(node->sz)、插入元素的大小(sz),以及插入元素后 ziplist 的 prevlen 占用大小。在计算完大小之后,_quicklistNodeAllowInsert 函数会依次判断新插入的数据大小(sz)是否满足要求,即单个 ziplist 是否不超过 8KB,或是单个 ziplist 里的元素个数是否满足要求。只要这里面的一个条件能满足,quicklist 就可以在当前的 quicklistNode 中插入新元素,否则 quicklist 就会新建一个 quicklistNode,以此来保存新插入的元素。

这样一来,quicklist 通过控制每个 quicklistNode 中,ziplist 的大小或是元素个数,就有效减少了在 ziplist 中新增或修改元素后,发生连锁更新的情况,从而提供了更好的访问性能。
而 Redis 除了设计了 quicklist 结构来应对 ziplist 的问题以外,还在 5.0 版本中新增了 listpack 数据结构,用来彻底避免连锁更新。

三、listpack

listpack 也叫紧凑列表,它的特点就是用一块连续的内存空间来紧凑地保存数据,同时为了节省内存空间,listpack 列表项使用了多种编码方式,来表示不同长度的数据,这些数据包括整数和字符串。
在这里插入图片描述
好了,了解了 listpack 的整体结构后,我们再来看下 listpack 列表项的设计。和 ziplist 列表项类似,listpack 列表项也包含了元数据信息和数据本身。不过,为了避免 ziplist 引起的连锁更新问题,listpack 中的每个列表项不再像 ziplist 列表项那样,保存其前一个列表项的长度,它只会包含三个方面内容,分别是:

  • 当前元素的编码类型(entry-encoding)
  • 元素数据 (entry-data)
  • 以及编码类型和元素数据这两部分的长度 (entry-len)

如下图所示:
在这里插入图片描述

在 listpack 中,因为每个列表项只记录自己的长度,而不会像 ziplist 中的列表项那样,会记录前一项的长度。所以,当我们在
listpack 中新增或修改元素时,实际上只会涉及每个列表项自己的操作,而不会影响后续列表项的长度变化,这就避免了连锁更新。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年用哪个思维导图软件好?这款在线工具堪称国产之光!

思维导图软件哪个好? 如今已经是2024年了,想做思维导图,面对琳琅满目的思维导图软件,哪一个才是最适合我们的呢? 在选用思维导图软件时,我们可能会综合考虑多个方面,譬如功能数量、操作易用性…

未来工作场所:知识中台与AI的融合

在快速迭代的未来工作场所,知识中台与AI的融合正引领着一场深刻的工作方式变革。这种融合不仅优化了企业的知识管理流程,还通过智能工具如AI问答、内容生成等,极大地提升了工作效率和决策质量。接下来,我们将以HelpLook AI知识库为…

【C/C++】C++类与对象基本概念(抽象与封装、构造函数、析构函数、静态、友元)

文章目录 七、类与对象基本概念抽象定义与声明访问控制类的实现与使用对象指针、this指针与对象引用构造函数析构函数拷贝构造函数 七、类与对象基本概念 抽象 抽象是相对,而非绝对的 在研究问题时,侧重点不同,可能会产生不同的抽象结果;解决…

解密低代码:持续更新的必要性与背后驱动力

在数字化转型的浪潮中,低代码(Low-Code)开发平台已经成为企业快速构建应用程序的重要工具。低代码平台通过图形化界面和少量手写代码,帮助开发者和业务人员在短时间内构建复杂应用。然而,随着技术的不断演进和业务需求…

【C#】Visual Studio代码格式化方法

1. 快捷键 选中内容后,先键入 ctrlk 再键入 ctrlf(注意:Visual Studio中标注两个快捷键的都是这样使用) 2. 工具栏 编辑 - 高级 - 设置选定内容的格式

mp3格式转换器免费版来袭,告别格式限制,音乐更自由!

当下,mp3格式可以说是音频文件的主流格式。无论是通过耳机、音箱还是车载音响,我们都在使用mp3格式来播放收听音乐。智能手机、平板电脑等移动设备上通常内置mp3播放器。mp3经常在视频剪辑中充当背景音乐和特效音效。 为什么mp3格式如此普遍&#xff1f…

PHP高效易用在线简单商城系统小程序源码

🚀高效易用的在线简单商城系统,让电商创业轻松启航🛍️ 🌈 一键开店,轻松上手 还在为繁琐的电商开店流程头疼吗?高效易用的在线简单商城系统,让你告别复杂设置,一键开启你的电商之旅…

leetcode日记(73)分隔链表

简单,但是链表问题容易犯错 第一次错误:每次遍历到小于x的节点移动到前面后都需要将a向后移动到移动后的该节点处,使得后面移动的节点都能移动到该节点后 第二次错误:看错了题目,需要从头开始遍历 第三次错误&#…

死抠细节!在ChatGPT的帮助下让论文精益求精!

学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 在撰写毕业论文的过程中,细节往往决定成败。无论是结构的合理性、论点的清晰度,还是语言的精准表达,每一个细节都影响着论文的最终质量。今天分享的内…

解决世界500强跨域跨境数据文件传输丢包严重、高延迟等问题

在当今全球化的商业环境中,大型跨国公司如世界500强企业,面临着跨地域数据传输的挑战。这些挑战包括数据包丢失、网络延迟、成本上升以及数据安全风险。传统的数据传输方法已难以满足这些企业对效率和安全性的需求。那么,如何为这些企业找到一…

虚拟机安装+xftp+xshell

1、VMware安装 下载VM,可以直接去官网下载,也可以直接提取我的网盘链接 通过百度网盘分享的文件:vmware 链接:百度网盘 请输入提取码 提取码:ms01 --来自百度网盘超级会员V2的分享 没有百度网盘会员的这里也有123…

vue3+vite项目中引入path模块报错

报错描述:Module "path" vite-browser-exter...h?t1700468860286:3 has been externalized for browser compatibility. Cannot access "path.resolve" in client code. 问题原因:vite 源码中设定了不允许在客户端代码中访问内置模…

STL中queue、stack的实现与容器适配器的讲解

目录 简介 栈(Stack) 队列(Queue) 实现 栈的实现 队列的实现 deque的讲解 deque的结构示意图 简介 栈(Stack)和队列(Queue)是两种基本的数据结构,在STL&#xff0…

【面积图表美化示例+讲解】

文章目录 效果预览:半透面积图:百分比堆积图: 效果预览: 半透面积图: 思路: 实际上是由两种类型的图表叠在一起,【面积图折线图】 处理: [1] 为了让面积图的边缘更加清晰&#xff…

ts发送邮箱,以网易邮箱来演示

①引入依赖: npm i nestjs-modules/mailer nodemailer 这里是引入相应的需要的依赖。 创建模块,以及服务 nest generate module sendEmail nest generate service sendEmail ②在app.module中注册,之后在其它的模块就可以使用 import { M…

员工飞单、走私单、离职带走客户,屡禁不止怎么办?1招防止!

企业面临着诸多挑战,其中员工行为不端,如飞单、走私单以及离职时带走客户等问题,不仅损害了企业的经济利益,更侵蚀了企业的市场竞争力与客户信任度。 这些问题如同一颗颗毒瘤,若不及时清除,将严重阻碍企业…

简而不减,极致便捷!泰极预付费解决方案震撼上市

开户麻烦!绑表复杂!用电情况模糊!电费收缴难! 在日常生活中,能源缴费可能经常会遇到运维难管理、缴费收益难计算、支付安全难保障等问题。如何解决呢?正泰物联推出“泰极预付费解决方案”,“简”操作,“不减”功能,有效解决上述问题,助力实现便捷生活。 享轻松:泰极简而不减…

three.js 编辑器,动画,着色器, cesium 热力图,聚合点位,大量点线面, 图层,主题,文字

对于大多数的开发者来言,看了很多文档可能遇见不到什么有用的,就算有用从文档上看,把代码复制到自己的本地大多数也是不能用的,非常浪费时间和学习成本, 尤其是three.js , cesium.js 这种难度较高&#xff…

【计算机组成原理】五、中央处理器:3.指令流水线(互斥、同步)

5.指令流水线 文章目录 5.指令流水线5.1基本概念5.2性能指标5.3指令流水线影响因素5.3.1结构相关(**资源冲突**):**互斥**5.3.2数据相关(**数据冲突**):**同步**5.3.3控制相关(**控制冲突**) 5.…

电脑网络设置

有时候开机会发现电脑明明练了Wifi却无法上网,是因为之前梯子没关直接关机,解决方案是 打开设置网络和Internet代理手动设置代理关闭“使用代理服务器”