前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis数据结构:List

Redis数据结构:List

原创
作者头像
阿成的春天和我的太阳
发布2024-08-12 23:38:44
650
发布2024-08-12 23:38:44
举报
文章被收录于专栏:末日狂奔

Redis 中的 list 是类似于双端队列的一种实现,其底层的数据结构涉及到 linkedlist、ziplist、quicklist 和 listpack 的演进

linkedlist

redis 中的 linkedlist 是双链表,这也是我们实现 list 时首先想到的数据结构之一。redis 中的双链表并没有非常特殊的地方,我们来简单看下对应的代码实现即可

代码语言:javascript
复制
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;

typedef struct listNode {
    struct listNode *prev;//前驱节点
    struct listNode *next;//后继节点
    void *value;//值
} listNode;

我们可以发现,双链表是一种非常标准的结构,链表维护首尾节点指针,维护长度,还和维护必要的工具函数指针地址,链表节点维护前驱、后继节点以及对应的值,正常来讲这套结构没有问题,但挑剔一点的话,它会有两个问题:

  1. 当数据较小的情况下,数据结构维护的额外信息比数据本身还要占内存
  2. 链表这种结构一个特点是内存不连续的,在遍历时效率较低

为了解决张两点,Redis 创造了 ziplist

ziplist

针对我们上面提到的两个问题,对应的解决思路就是结构简单+内存连续,而 ziplist 正是这样一种结构。

ziplist 首先是一块连续的内存,然后按一定的规范维护了简单的节点结构,如下图所示

ziplist 各组成部分功能为:

  • zlbytes:ziplist 占用的总字节数
  • zltail:尾结点的偏移量
  • zllen:维护的节点数
  • entries:节点信息
    • prelen:前一个节点占用的字节数。根据前一个节点的大小不同,会有两种表示方式
      • 当前一个节点字节数小于 254 时(即 11111110),prelen 用 1 字节表示
      • 当前一个节点字节数大于等于 254 时,prelen 用 5 字节表示,第一字节恒为 11111110,后面四个字节用于表示真实字节数
    • encoding:用于表示当前 entry 的类型和长度
      • 前两位表示类型,11 表示 int 型数据,其余表示字符串
    • entry-data:节点数据,特殊的,当 entry 中存储的是 int 类型时,entry-data 会合并到 encoding 中,此时就没有 entry-data 这部分
  • zlend:结尾特殊字节,恒为 255,即 11111111

我们看到 ziplist 节点没有维护首尾指针,又针对不同情况实现各种变长存储,为了应对变长存储下的变量,维护了一个 prelen 字段,可以理解为用时间换了部分空间,在数据量小的情况下会有不错表现,但是它有个注明的缺点:连锁更新

我们现在知道,对于节点序列 ABC,节点 A 的长度可能会影响到节点 B 的 prelen 的长度,而节点 B 的 prelen 字段长度变更会导致节点 B 整体长度变更,这就有可能触发节点 C 遇到类似的情况,所以在极端场景下,一个节点数据的变更可能会引发后续节点的连锁反应,这就是 ziplist 的连锁更新。

为了解决连锁更新的问题,redis 又造了一个新的结构:quicklist

quicklist

todo

listpack

todo

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • linkedlist
    • ziplist
      • quicklist
        • listpack
        相关产品与服务
        云数据库 Redis
        腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档