redis底层数据结构-List

article/2025/9/13 21:55:38

举例分析

创建列表对象 numbers

 列表对象有两种底层实现结构

1.压缩列表(zipList)实现的列表对象

压缩列表(zipList)是Redis为了节省内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个压缩列表可以包含任意多个节点(entry),每个节点可以保存一个字节数组或者一个整数值,如图

 压缩列表的每个节点Entry构成如下

previous_entry_ength:以字节为单位,记录了压缩列表中前一个字节的长度。利用此原理即当前节点位置减去上一个节点的长度即得到上一个节点的起始位置,压缩列表可以从尾部向头部遍历,这么做很有效地减少了内存的浪费。

encoding:记录了节点的 content 属性所保存数据的类型以及长度。

content:保存节点的值,节点的值可以是一个字节数组或者整数,值的类型和长度由节点的 encoding 属性决定。

ZipList优缺点

压缩列表ziplist结构本身就是一个连续的内存块,由表头、若干个entry节点和压缩列表尾部标识符zlend组成,通过一系列编码规则,提高内存的利用率,使用于存储整数和短字符串。
压缩列表ziplist结构的缺点是:每次插入或删除一个元素时,都需要进行频繁的调用realloc()函数进行内存的扩展或减小,然后进行数据”搬移”,甚至可能引发连锁更新,造成严重效率的损失。

2. 双端链表(LinkedList)实现的列表对象

 链表是一种常用的数据结构,C 语言内部是没有内置这种数据结构的实现,所以Redis自己构建了链表的实现。链表节点定义:

多个 listNode 可以通过 prev 和 next 指针组成双端链表,结构如下

 另外提供了操作链表的list结构

list结构为链表提供了表头指针 head ,表尾指针 tail 以及链表长度计数器 len ,dup、free、match 成员则是用于实现多态链表所需的类型特定函数。

Redis链表实现的特性:

双端:链表节点带有 prev 和 next 指针,获取某个节点的前置节点和后置节点复杂度都是O(1)。

无环:表头节点的 prev 指针和表尾节点的 next 指针都指向 NULL,对链表的访问以NULL为终点。

带表头指针和表尾指针:通过list结构的 head 和 tail 指针,程序获取链表的表头节点和表尾结点的复杂度都是O(1)。

带链表长度计数器:程序使用 list 结构的 len属性对 list持有的链表节点进行计数,程序获取链表中节点数量的复杂度为O(1)。

多态:链表节点使用 void* 指针来保存节点值,并且通过 list 结构的 dup、 free、match 三个属性为节点值设置类型特定函数,所以链表可以用于保存各种不同类型的值。

 ziplist 与 linkedlist 之间存在着一种编码转换机制当列表对象可以同时满足下列两个条件时,列表对象采用ziplist编码,否则采用linkedlist编码:

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

(2)列表元素保存的元素数量小于512个;

以上两个条件的上限值可以在配置文件中修改 list-max-ziplist-value 选项和 list-max-ziplist-entries 选项 。

另外对于使用 ziplist 编码的列表对象,当以上两个条件中任何一个不能满足时,对象的编码转换操作就会执行,原本保存在压缩列表里面的所有列表元素都会被转移并保存到双端链表里面,对象的编码也从 ziplist 变为 linkedlist 。

 但是如果我们实际操作下的话,是这样懵逼的情况:

 

 原来是redis 在 3.2 版本的时候,考虑到redis的空间存储效率和时间效率,引入了quicklist(快速列表)作为 list 的底层实现

quicklist

quicklist是由ziplist组成的双向链表,链表中的每一个节点都以压缩列表ziplist的结构保存着数据,而ziplist有多个entry节点,保存着数据。相当于一个quicklist节点保存的是一片数据,而不再是一个数据。

例如:一个quicklist有4个quicklist节点,每个节点都保存着1个ziplist结构,每个ziplist的大小不超过8kb,ziplist的entry节点中的value成员保存着数据。

根据以上描述,总结出一下quicklist的特点:

quicklist宏观上是一个双向链表,因此,它具有一个双向链表的优点,进行插入或删除操作时非常方便,虽然复杂度为O(n),但是不需要内存的复制,提高了效率,而且访问两端元素复杂度为O(1)。
quicklist微观上是一片片entry节点,每一片entry节点内存连续且顺序存储,可以通过二分查找以 log2(n)log2(n) 的复杂度进行定位。
总体来说,quicklist给人的感觉和B树每个节点的存储方式相似。

在quicklist表头结构中,有两个成员是fill和compress,其中” : “是位域运算符,表示fill占int类型32位中的16位,compress也占16位。

fill和compress的配置文件是redis.conf。

fill成员对应的配置:list-max-ziplist-size -2
当数字为负数,表示以下含义:
-1 每个quicklistNode节点的ziplist字节大小不能超过4kb。(建议)
-2 每个quicklistNode节点的ziplist字节大小不能超过8kb。(默认配置)
-3 每个quicklistNode节点的ziplist字节大小不能超过16kb。(一般不建议)
-4 每个quicklistNode节点的ziplist字节大小不能超过32kb。(不建议)
-5 每个quicklistNode节点的ziplist字节大小不能超过64kb。(正常工作量不建议)
当数字为正数,表示:ziplist结构所最多包含的entry个数。最大值为 215215。
compress成员对应的配置:list-compress-depth 0
后面的数字有以下含义:
0 表示不压缩。(默认)
1 表示quicklist列表的两端各有1个节点不压缩,中间的节点压缩。
2 表示quicklist列表的两端各有2个节点不压缩,中间的节点压缩。
3 表示quicklist列表的两端各有3个节点不压缩,中间的节点压缩。
以此类推,最大为 216216。

quicklist 结构图

根据上述结构体定义,咱们可以绘制一下 quicklist 的结构

总结

A、双端链表

1.双端链表便于在表的两端进行 push 和 pop 操作,但是它的内存开销比较大;

2.双端链表每个节点上除了要保存数据之外,还要额外保存两个指针;

3.双端链表的各个节点是单独的内存块,地址不连续,节点多了容易产生内存碎片;

B压缩列表

1.ziplist 由于是一整块连续内存,所以存储效率很高;

2.ziplist 不利于修改操作,每次数据变动都会引发一次内存的 realloc;

3.当 ziplist 长度很长的时候,一次 realloc 可能会导致大批量的数据拷贝,进一步降低性能;

CquickList

1.空间效率和时间效率的折中;

2.结合了双端链表和压缩列表的优点;

应用场景

接收关注的商品变动发消息

Lpush user1 sku01 sku02

lpush sku01 msgId

Lpush sku01 msgid2

查询消息

Lrange user1 0 2

Lrange sku01 0 10

Lrange sku02 0 10


http://chatgpt.dhexx.cn/article/y8C8smPI.shtml

相关文章

redis中hash数据结构

目录 hash的数据结构ziplist底层实现字典底层实现扩容缩容 引用 hash的数据结构 hash底层数据结构的实现包括两种:ziplist和字典当保存的所有键值对字符串长度小于 64 字节并且键值对数量小于 512 时使用ziplist ,否则使用字典的方式 ziplist底层实现 …

redis的五种数据结构

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、字符串(String) 1.SDS的定义 2.SDS与C语言中字符串的区别(优点) 2.1 获取字符串长度 2.2 防止缓冲区的溢…

「Redis数据结构」哈希对象(Hash)

「Redis数据结构」哈希对象(Hash) 文章目录 「Redis数据结构」哈希对象(Hash)一、概述二、编码ZipListHashTable 三、编码转换 一、概述 Redis中hash对象是一个string类型的field和value的映射表,hash特别适合用于存储…

Redis底层数据结构(图文详解)

目录 前言 Redis为什么要使用2个对象?两个对象的好处 redisObject对象解析 String 类型 1、int 整数值实现 2、embstr 3、raw List 类型 1、压缩链表:ziplist 2、双向链表:linkedlist 3、快速列表:quicklist Hash …

Redis数据结构之hash

对象类数据的存储如果具有较频繁的更新需求操作会显得笨重,这里我们可以用redis的hash数据类型解决。 一、hash类型 新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息 需要的存储结构:一个存储…

Redis数据结构之Zset

文章目录 一、zset数据结构二、跳表skipList什么是跳表?1.跳表的查找2.跳表的插入3.跳表的删除4.跳表的更新 一、zset数据结构 相比于set,sorted set 增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,还可以…

Redis数据结构有哪些

Redis数据结构有哪些 一、Redis数据结构 一、Redis数据结构 Redis是一种基于内存的数据库,并且提供一定的持久化功能,它是一种键值(key-value)数据库,使用 key 作为 索引找到当前缓存的数据,并且返回给程序…

「Redis数据结构」压缩列表(ZipList)

「Redis数据结构」压缩列表(ZipList) 文章目录 「Redis数据结构」压缩列表(ZipList)一、概述二、结构三、连锁更新问题四、压缩列表的缺陷五、小结参考 ZipList 是一种特殊的“双端链表” ,由一系列特殊编码的连续内存…

redis数据结构hash

Redis数据结构之hash Hash存储结构 Hash是一个string 类型的field和value的映射表。Hash特别适合存储对象,相对于将对象的每个字段存成单个string 类型。一个对象存储在Hash类型中会占用更少的内存,并且可以更方便的存取整个对象。 我们简单举个实例来…

简述redis数据结构

String:字符串 List:列表 Hash:哈希表 Set:无序集合 Sorted Set:有序集合 bitmap:布隆过滤器 GeoHash:坐标,借助Sorted Set实现,通过zset的score进行排序就可以得到坐标附…

Redis数据结构之——hash

写在前面 以下内容是基于Redis 6.2.6 版本整理总结 一、Redis 数据结构hash的编码格式 Redis中hash数据类型使用了两种编码格式:ziplist(压缩列表)、hashtable(哈希表) 在redis.conf配置文件中,有以下两个参数,意思为:当节点数量小于512并…

Redis底层数据结构详解

Redis底层数据结构详解 我们知道Redis常用的数据结构有五种,String、List、Hash、Set、ZSet,其他的集中数据结构基本上也是用这五种实现的,那么,这五种是Redis提供给你的数据结构,这五种数据结构式怎么实现的&#xf…

Redis的五种基础数据结构

Redis的五种基础数据结构 Redis有5种基础数据结构,分别为:String(字符串),list(列表),hash(字典),set(集合)和zset(有序集合)。 1.String(字符串) 字符串的结构 字符串String是Redis最简单的数据结构,它的内部表示…

Redis的数据结构

一、redis的数据结构 1、String字符串类型 Redis的String能够表示字符串、整数、浮点数三种值的类型 应用场景: 普通的赋值使用incr、decr命令进行递增和递减统计数据。用于实现乐观锁watch(事物)setNx实现分布式锁 底层数据类型: // 数据结构 stru…

为了拿捏 Redis 数据结构,我画了 40 张图(完整版)

大家好,我是小林。 Redis 为什么那么快? 除了它是内存数据库,使得所有的操作都在内存上进行之外,还有一个重要因素,它实现的数据结构,使得我们对数据进行增删查改操作时,Redis 能高效的处理。…

IDEA 配置Services面板

IDEA中的services窗口是一个管理所有服务的地方,特别是在使用spring cloud项目开发中,对多个微服务的管理非常实用。 配置方式一: 在IDEA中可通过配置将services窗口面板显示出来。 配置方式二: 找到项目.idea目录下worksp…

如何在IDEA配置Tomcat

1、点击RUN下拉的Edit Configurations 2、点击左上角号,下拉找到Tomcat Server,选择Local 3、 配置Tmcat信息 4、点击Deployment,选择右边的号,选择Artifict 5、Application context这里只写个“/”就可以了 6、点击Apply,然后返回…

idea配置代理服务器

1、查看代理服务器ip和端口 使用http代理 2、idea中配置代理服务器 选择File --> Settings --> 搜索HTTP Proxy --> 选择Manual proxy configuration --> 选择HTTP输入ip和端口 --> 点击Apply 3、配置jvm启动参数 -Djava.net.useSystemProxiestrue 完成!

IDEA配置安卓环境

IDEA是JetBrains公司推出的Java集成开发环境 ,这学期又开了安卓课,少不了安卓环境,不过android stdio是完全支持安卓的,不适合开发java项目,作为小白,我觉得IDEA一个软件就够了,当然&#xff0c…

idea配置maven仓库

1、去达内开发文档服务器下载对应插件 达内开发文档服务器 找到配置文件下载 ,下载阿里云Maven创库配置 以上下载压缩包先不动 2、创建maven项目 打开idea file-----new project 点击左侧选择maven然后next 3、然后查看对应的maven路径 点击file---setting 每个…