5分钟了解Redis的内部实现快速列表(quicklist)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 在Redis3 .2版本之前,存储列表(list)数据结构使用的是压缩列表(ziplist)和链表(linkedlist),当列表元素个数比较少并且每个元素占用空间比较小的时候,使用压缩列表。当列表元素个数比较多或者某个元素占用空间比较大的时候,使用链表。

快速列表简介

在Redis3 .2版本之前,存储列表(list)数据结构使用的是压缩列表(ziplist)和链表(linkedlist),当列表元素个数比较少并且每个元素占用空间比较小的时候,使用压缩列表。当列表元素个数比较多或者某个元素占用空间比较大的时候,使用链表。

考虑到链表的附加空间相对太高,结点的内存也是单独分配的,影响内存管理效率。在Redis3 .2版本开始对列表数据结构进行了改造,使用快速列表(quicklist)代替了压缩列表(ziplist)和链表(linkedlist)。

快速列表(quicklist)是以压缩列表(ziplist)为节点的链表(linkedlist),将链表按段切分,每一段使用压缩列表进行内存的连续存储,多个压缩列表通过prev和next指针组成的双向链表。它结合了压缩列表和链表的优势,进一步压缩了内存的使用量,进一步提高了效率。

下面我们了解一下快速列表的具体实现。

快速列表的实现

在Redis中的快速列表是由quicklist结构表示的,quicklist结构包含由多个快速列表结点组成的双向链表,每一个快速列表结点都保存了一个压缩列表。下面我们一个一个地详细了解一下。

quicklist结构

快速列表是由quicklist结构表示的,它包含以下几个属性:

  • head属性: 指向头部快速列表结点的指针。
  • tail属性:指向尾部快速列表结点的指针。
  • count属性:在所有压缩列表中元素的个数总和。
  • len属性:快速列表结点的个数。
  • fill属性:压缩列表的最大大小,存放list-max-ziplist-size参数的值。当超出了这个配置,就会新建一个压缩列表。
  • compress属性:结点压缩深度,存放list-compress-depth参数的值。
  • bookmarks属性:用来快速列表重新分配内存空间时使用的数组,不使用时不占用空间。
  • bookmark_count属性:bookmarks数组的大小。

快速列表结点

快速列表结点使用quicklistNode结构表示,它包含以下几个属性:

  • prev属性:指向前一个快速列表结点的指针。
  • next属性:指向后一个快速列表结点的指针。
  • zl属性:指向压缩列表的指针,如果当前结点的数据被压缩,那么它指向一个quicklistLZF结构。
  • sz属性:压缩列表的所占字节总数。
  • count属性:压缩列表中的元素数量。
  • encoding属性:存储形式,原生字节数组还是LZF压缩存储。
  • recompress属性:当查看了某一项被压缩的数据时,需要把数据暂时解压,这时就设置 recompress = 1 做一个标记,等有机会再把数据重新压缩。

quicklistLZF结构

当快速列表结点数据被压缩时,数据会被存放在quicklistLZF结构中,它包含以下几个属性:

  • sz属性:表示压缩后的大小。
  • compressed属性:存放压缩后的字节数组。

快速列表的压缩机制

在快速列表中,两端结点的数据被访问的可能性比较高,中间结点的数据被访问的可能性比较低。如果我们的应用场景符合这个特点,可以把中间结点的数据使用 LZF 算法进行压缩,从而进一步节省内存空间。我们可以对list-compress-depth参数进行配置。

默认情况下,list-compress-depth参数为0,也就是不压缩数据;当该参数被设置为1时,除了头部和尾部之外的结点都会被压缩;当该参数被设置为2时,除了头部、头部的下一个、尾部、尾部的上一个之外的结点都会被压缩;当该参数被设置为2时,除了头部、头部的下一个、头部的下一个的下一个、尾部、尾部的上一个、尾部的上一个的上一个之外的结点都会被压缩;以此类推。

最后,谢谢你这么帅,还给我 点赞关注
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
存储 NoSQL Redis
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
77 1
|
10天前
|
消息中间件 存储 NoSQL
4)深度解密 Redis 的列表(List)
4)深度解密 Redis 的列表(List)
14 1
|
2月前
|
存储 NoSQL 算法
Redis6入门到实战------ 三、常用五大数据类型(列表(List)、集合(Set)、哈希(Hash)、Zset(sorted set))
这是关于Redis 6入门到实战的文章,具体内容涉及Redis的五大数据类型:列表(List)、集合(Set)、哈希(Hash)、有序集合(Zset(sorted set))。文章详细介绍了这些数据类型的特点、常用命令以及它们背后的数据结构。如果您有任何关于Redis的具体问题或需要进一步的帮助,请随时告诉我。
|
3月前
|
存储 NoSQL 容灾
Redis问题之压缩列表zipList在Redis中有哪些应用场景
Redis问题之压缩列表zipList在Redis中有哪些应用场景
|
3月前
|
缓存 监控 NoSQL
若依修改----监控相关,主要包括在线用户,数据监控,服务监控,缓存监控,缓存列表,缓存监控有助于帮我们搞清楚redis的缓存情况,数据监控的密码控制台管理用户名和密码在application-dru
若依修改----监控相关,主要包括在线用户,数据监控,服务监控,缓存监控,缓存列表,缓存监控有助于帮我们搞清楚redis的缓存情况,数据监控的密码控制台管理用户名和密码在application-dru
|
3月前
|
存储 NoSQL Java
Redis10------Set类型,存在着无序的特征存储的顺序和插入的顺序是无关的,set集合的一大特点是不可重复,在redis中支持交集插集等特殊功能,好友列表,共同关注等等
Redis10------Set类型,存在着无序的特征存储的顺序和插入的顺序是无关的,set集合的一大特点是不可重复,在redis中支持交集插集等特殊功能,好友列表,共同关注等等
|
3月前
|
NoSQL Java Redis
Redis09-----List类型,有序,元素可以重复,插入和删除快,查询速度一般,一般保存一些有顺序的数据,如朋友圈点赞列表,评论列表等,LPUSH user 1 2 3可以一个一个推
Redis09-----List类型,有序,元素可以重复,插入和删除快,查询速度一般,一般保存一些有顺序的数据,如朋友圈点赞列表,评论列表等,LPUSH user 1 2 3可以一个一个推
|
4月前
|
存储 NoSQL 安全
Redis第六弹-List列表-(相当于数组/顺序表)Lpush key element-一次可以插入多个元素(假如key已经存在,并且key对应的value并非是list,则会报错)
Redis第六弹-List列表-(相当于数组/顺序表)Lpush key element-一次可以插入多个元素(假如key已经存在,并且key对应的value并非是list,则会报错)
|
4月前
|
NoSQL Java Redis
【Redis】 Java操作客户端命令——列表操作与哈希操作
【Redis】 Java操作客户端命令——列表操作与哈希操作
|
4月前
|
存储 NoSQL Redis
Redis第四弹,Redis实现list时候做出的优化ziplist(压缩链表,元素少的情况),可更好的节省空间list——(内部编码:quicklist)Object encoding
Redis第四弹,Redis实现list时候做出的优化ziplist(压缩链表,元素少的情况),可更好的节省空间list——(内部编码:quicklist)Object encoding