Redis数据结构7:REDIS_QUICKLIST&REDIS_LISTPACK
  EYmIKSPPfzd2 2023年12月15日 21 0

REDIS_QUICKLIST

quickList(快速列表)是Redis对List对象的一个实践。

在 Redis 3.0 之前,List 对象的底层数据结构是双向listNode或者zipList。

在 Redis 3.2 更新中,List 对象的底层改由 quickList 实现

前文提到,zipList当元素个数比较多时,每当修改元素时,必须重新分配存储空间,对执行效率影响很大。

quickList本质上是listNode+zipList的组合,quickList的顶层设计就是一个链表,链表的每个节点就是一个zipList。

从源码分析结构

// QuickList顶层链表
typedef struct quicklist {
    // 链表头
    quicklistNode *head;
    // 链表尾
    quicklistNode *tail; 
    // 所有zipList总元素个数
    unsigned long count;
    // node个数
    unsigned long len;       
    ...
} quicklist;
// QuickList节点设计
typedef struct quicklistNode {
    // 前指针
    struct quicklistNode *prev;
    // 后指针
    struct quicklistNode *next;
    // 该节点所指向的zipList指针
    unsigned char *zl;              
    // zipList的的字节大小
    unsigned int sz;                
    // zipList的元素个数
    unsigned int count : 16;        //ziplist中的元素个数 
    ....
} quicklistNode;

用图表达:

10.png

在向 quicklist 添加一个元素的时候,会先检查插入位置的压缩列表是否能容纳该元素,如果能容纳就直接保存到 quicklistNode 结构里的压缩列表,如果不能容纳,才会新建一个新的 quicklistNode 结构。

quicklist 会控制 quicklistNode 结构里的压缩列表的大小或者元素个数,来规避潜在的连锁更新的风险,但是这并没有完全解决连锁更新的问题

REDIS_LISTPACK

Redis在5.0设计了一个新的数据结构:listPack,用于替代zipList。

它最大特点是 listpack 中每个 entry 不再包含前一个节点的长度。

zipList正因需要保存前一个节点的长度字段,才导致了连锁更新的隐患。

在Redis7.0版本中已经用listPack重构。

结构设计

11.png

在每个Entry中,又包含如下结构:

12.png

  • encoding用于定义该元素的编码类型,会对不同长度的整数和字符串进行编码;
  • data存放实际数据;
  • len代表encoding+data的总长度;

listPack之于zipList最大的改变就是不再记录前一个节点的字段长度,这样无论节点如何变化,每个节点都不再因为其他节点的更新而连锁更新。

listPack如何逆向遍历

uint64_t lpDecodeBacklen(unsigned char *p) {
    uint64_t val = 0;
    uint64_t shift = 0;
    do {
        val |= (uint64_t)(p[0] & 127) << shift;
        if (!(p[0] & 128)) break;
        shift += 7;
        p--;
        if (shift > 28) return UINT64_MAX;
    } while(1);
    return val;
}

从当前列表项起始位置的指针开始,向左逐个字节解析,得到前一项的 entry-len 值。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月15日 0

暂无评论

推荐阅读
  rvP2pqm8fEoB   2023年12月24日   34   0   0 ListJavaListJava
EYmIKSPPfzd2