【Redis系列3】Redis列表对象之linkedlist(双端列表)和ziplist(压缩列表)及quicklick(快速列表)实现原理分析

前言

上一篇我们分析了字符串对象的底层存储结构SDS,那么这一篇我们继续分析Redis中5种常用数据类型的第2种基本数据类列表对象的底层存储结构。

列表对象

Redis3.2之前,列表对象其底层存储结构可以有两种,即:linkedlistziplist,而在Redis 3.2之后,列表对象底层存储结构优化成为了另一种:quicklist。而quicklist可以认为是linkedlistziplist的结合体。

列表内部使用哪一种类型也是通过编码来进行区分:

编码属性 描述 object encoding命令返回值
OBJ_ENCODING_LINKEDLIST 使用linkedlist实现列表对象 linkedlist
OBJ_ENCODING_ZIPLIST 使用ziplist实现列表对象 ziplist
OBJ_ENCODING_QUICKLIST 使用quicklist实现列表对象 quicklist

linkedlist

linkedlist是一个双向列表,每个节点都会存储指向上一个节点和指向下一个节点的指针。linkedlist因为每个节点的空间是不连续的,所以可能会造成过多的空间碎片。

linkedlist存储结构

链表中每一个节点都是一个listNode对象(源码adlist.h内),不过需要注意的是,列表中的value其实也是一个字符串对象,后面我们介绍的其他几种数据类型其内部最终也是会嵌套字符串对象:

typedef struct listNode {
   
    struct listNode *prev;//前一个节点
    struct listNode *next;//后一个节点
    void *value;//值(字符串对象)
} listNode;

然后会将其再进行封装成为一个list对象(源码adlist.h内):

typedef struct list {
   
    listNode *head;//头节点
    listNode *tail;//尾节点
    void *(*dup)(void *ptr);//节点值复制函数
    void (*free)(void *ptr);//节点值释放函数
    int (*match)(void *ptr, void *key);//节点值对比函数
    unsigned long len;//节点数量
} list;

Redis中对linkedlist的访问是以NULL值为终点的,因为head节点的prev节点为NULL,tail节点的next节点为NULL。

所以,同样的,在Redis3.2之前我们可以得到如下简图:
在这里插入图片描述
PS:想要详细了解dictEntryredisObject对象以及编码相关知识的的可以点击这里

ziplist

ziplist是为了节省内存而开发的一种压缩列表数据结构,后面讲述的哈希数据类型底层也用到了ziplist

ziplist是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个ziplist可以包含任意多个entry,而每一个entry又可以保存一个字节数组或者一个整数值。

ziplist和linkedlist最大的区别是ziplist不存储指向上一个节点和下一个节点的指针,存储的是上一个节点的长度和当前节点的长度,牺牲了部分读写性能来换取高效的内存利用率,是一种时间换空间的思想。

ziplist适用于字段个数少和字段值少的场景。

ziplist存储结构

ziplist的组成结构为:

<zlbytes
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

双子孤狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值