《闲扯Redis五》List数据类型底层之quicklist

10 阅读 作者:大道七哥 2020-10-23

一、前言

Redis 提供了5种数据类型:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要。

图片描述

Redis 中的 list 是我们经常使用到的一种数据类型,根据使用方式的不同,可以应用到很多场景中。

二、底层解析

1、上节回顾

 上节**《闲扯Redis四》List数据类型底层编码转换** 说道,在 3.0 版本的 Redis 中,List 类型有两种实现方式:

1、使用压缩列表(ziplist)实现的列表对象。

2、使用双端链表(linkedlist)实现的列表对象。

在 3.2 版本后新增了 quicklist 数据结构实现了 list,现在就来分析下 quicklist 的结构

2、官方描述

 先来看看 Redis 官方对 quicklist 的描述:

    A doubly linked list of ziplists

    A generic doubly linked quicklist implementation

 可见 quicklist 是一个双向链表,并且是一个 ziplist 的双向链表,也就是说 quicklist 的每个节点都是一个 ziplist。而通过前面的文章咱们可以知道,ziplist 本身也是一个能维持数据项先后顺序的列表,而且数据项保存在一个连续的内存块中。那是不是意味着 quicklist 结合了压缩列表和双端链表的特点呢!图片描述

3、结构分析

quicklist 结构定义

/* 
 * quicklist
 */
typedef struct quicklist {
    //头结点
    quicklistNode *head; 
    //尾节点
    quicklistNode *tail; 
    //所有ziplist中entry数量
    unsigned long count; 
    //quicklistNodes节点数量
    unsigned int len;   
    //ziplist中entry能保存的数量,由list-max-ziplist-size配置项控制 
    int fill : 16;       
    //压缩深度,由list-compress-depth配置项控制
    unsigned int compress : 16; 
} quicklist;

quicklist 结构属性注释

注释:

fill :ziplist 中 entry 能保存的数量,由 list-max-ziplist-size 配置项控制

    表示了单个节点(quicklistNode)的负载比例(fill factor),负数限制 quicklistNode 中的 ziplist 的字节长度, 正数限制 quicklistNode 中的 ziplist 的最大长度。
-5: 最大存储空间: 64 Kb <-- 通常情况下不要设置这个值
-4: 最大存储空间: 32 Kb <-- 非常不推荐
-3: 最大存储空间: 16 Kb <-- 不推荐
-2: 最大存储空间: 8 Kb <-- 推荐
-1: 最大存储空间: 4 Kb <-- 推荐
对于正整数则表示最多能存储到你设置的那个值, 当前的节点就装满了
通常在 -2 (8 Kb size) 或 -1 (4 Kb size) 时, 性能表现最好

compress :压缩深度,由 list-compress-depth 配置项控制

    表示 quicklist 中的节点 quicklistNode, 除开最两端的 compress 个节点之后, 中间的节点都会被压缩(LZF压缩算法)。

quicklistNode 结构定义

typedef struct quicklistNode {
    //前节点指针
    struct quicklistNode *prev; 
    //后节点指针
    struct quicklistNode *next; 
    //数据指针。当前节点的数据没有压缩,那么它指向一个ziplist结构;否则,它指向一个quicklistLZF结构。
    unsigned char *zl;
    //zl指向的ziplist实际占用内存大小。需要注意的是:如果ziplist被压缩了,那么这个sz的值仍然是压缩前的ziplist大小
    unsigned int sz;  
    //ziplist里面包含的数据项个数
    unsigned int count : 16;   
    //ziplist是否压缩。取值:1--ziplist,2--quicklistLZF 
    unsigned int encoding : 2; 
    //存储类型,目前使用固定值2 表示使用ziplist存储
    unsigned int container : 2; 
    //当我们使用类似lindex这样的命令查看了某一项本来压缩的数据时,需要把数据暂时解压,这时就设置recompress=1做一个标记,等有机会再把数据重新压缩
    unsigned int recompress : 1;
    unsigned int attempted_compress : 1; /* node can't compress; too small */
    unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;

quicklistLZF 结构定义

typedef struct quicklistLZF {
    unsigned int sz;  //压缩后的ziplist大小
    char compressed[];//柔性数组,存放压缩后的ziplist字节数组
} quicklistLZF;

4、quicklist 结构图

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

三、要点总结

1、双端链表

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

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

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

2、压缩列表

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

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

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

3、quicklist

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

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

点击查看更多内容
原文地址:https://www.imooc.com/article/303726
广告一下
热门教程
PHP7报A non well formed numeric value encountered 0
Linux系统下关闭mongodb的几种命令分享 0
mongodb删除数据、删除集合、删除数据库的命令 0
Git&Github极速入门与攻坚实战课程 0
python爬虫教程使用Django和scrapy实现 0
libnetsnmpmibs.so.31: cannot open shared object file 0
数据结构和算法视频教程 0
redis的hash结构怎么删除数据呢? 0
C++和LUA解析器的数据交互实战视频 0
mongodb errmsg" : "too many users are authenticated 0
C++基础入门视频教程 0
用30个小时精通C++视频教程可能吗? 0
C++分布式多线程游戏服务器开发视频教程socket tcp boost库 0
C++培训教程就业班教程 0
layui的util工具格式时间戳为字符串 0
C++实战教程之远程桌面远程控制实战 1
网络安全培训视频教程 0
LINUX_C++软件工程师视频教程高级项目实战 0
C++高级数据结构与算法视频教程 0
跨域问题很头疼?通过配置nginx轻松解决ajax跨域问题 0
相关文章
【译】JavaScript数据结构(3):单向链表与双向链表 16
10个JavaScript难点 16
【译】苹果拒绝支持PWA,有损Web的未来 16
iView 一周年了,同时发布了 2.0 正式版,但这只是开始... 16
nodejs+mongodb构建一个简单登录注册功能 16
【译】JavaScript数据结构(4):树 16
组件化开发与黑箱 16
TypeScript - 不止稳,而且快 16
webpack3+anujs+ReactCSSTransitionGroup 16
原生js实现图片放大镜效果 16
WEB缓存探究第二弹——实战 16
纯笔记:vfork 的一些使用场景(顺便讲一下 fork 的原理) 16
Android APP 内部捐赠实现(支付宝&amp;微信) 16
WKWebView 的一些小总结 16
模型评价(一) AUC大法 16
开始使用GraphQL 16
Webpack模块化原理简析 16
gulp使用问题记录 16
使用Angular4动画为页面添彩 16
Python27 Matplotlib (win64 python2.7) 安装及简单使用 16