【Redis】底层探析 I - Redis 有序集合(ZSet)是如何实现的?

目录

ZSet的编码方式

什么是跳跃列表(skiplist)?

ZSet的底层结构

跳跃列表的查询过程


ZSet的编码方式

        Redis中的有序集合zset底层实现采用了两种编码方式:

  • REDIS_ENCODING_SKIPLIST 跳跃列表
  • REDIS_ENCODING_ZIPLIST 压缩列表

        对于不同编码的触发方式/条件,有两个关键因素:

  • zset-max-ziplist-entries 128
  • zset-max-ziplist-value 64

        当有序集合的元素个数 ≥ zset-max-ziplist-entries (128个) ,或每个元素成员的长度≥zset-max-ziplist-value (默认为64字节)时,使用跳跃列表和哈希表作为有序集合的内部实现。

拓展:

        可以通过在Redis配置文件中(redis.conf)中定义使用两种不同编码的时机。

什么是跳跃列表(skiplist)?

        跳跃列表是一种有序的数据结构(有些版本会说是一种随机化的数据结构,这里的随机化是指概率),由William Pugh在论文​​​​​《Skip Lists: A Probabilis ... Trees》中提出。根据不同层级定向引导每一节点指向后续节点,达到快速访问指定节点的目的。跳跃列表在查找指定节点时,平均时间复杂度为O(logN)最坏情况下时间复杂度为O(N)

ZSet的底层结构

/* ZSETs use a specialized version of Skiplists */



///     ele: 当前节点元素,用以存储数据
///     score: 当前元素成员所对应的分数
///     backward:用以指向前驱节点的指针,即回溯指针
///     level:用以表示层级,每一层级对应指向一个指针 forward
///     forward:指向位于表尾方向其他节点的指针。
///     span:当前节点到forward指向的节点所跨越的节点个数。


typedef struct zskiplistNode {
    sds ele;
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        unsigned long span;
    } level[];
} zskiplistNode;


///     header: 指向头部跳跃表节点的指针。
///     tail:指向尾部跳跃表节点的指针。
///     length:表示跳跃表中的节点总数。
///     level:表示跳跃表中层数最大的节点的层数,表头节点的层数不计算在内。


typedef struct zskiplist {
    struct zskiplistNode *header, *tail;
    unsigned long length;
    int level;
} zskiplist;

typedef struct zset {
    dict *dict;
    zskiplist *zsl;
} zset;

【Redis】底层探析 I - Redis 有序集合(ZSet)是如何实现的?_第1张图片

        从图例和代码中我们不难发现,Redis中zset结构体由zskiplistdict组成,同时zskiplist结构体中包含有跳跃表节点 zskiplistNode跳跃表层级 zskiplistLevel,以此组成了一个双向链表结构

跳跃列表的查询过程

        接下来让我们分析一下跳跃表在查询时的过程。

【Redis】底层探析 I - Redis 有序集合(ZSet)是如何实现的?_第2张图片

        在上图中,跳表层级为4层,元素个数为10个,按照自顶向下的顺序进行查找,从顶层(第4层)开始查找元素值17: 

  • 第四层:找到元素值7,但发现7≤17,继续往右找;找到元素值29,但发现7≤29,回溯到上一指向元素值7的指针并向下走一层
  • 第三层:找到元素值25,但发现25≥17,回溯到指向元素值7的指针并向下走一层
  • 第二层:找到元素值16,但发现16≤17,继续往右找;找到元素值17,命中查找值,检索成功

        

        在下一章节,我们将就ZSet中使用的算法和代码实现作进一步阐析,并对性能和背后的数学原理作进一步探究。​​​​​​​

你可能感兴趣的:(数据库原理及应用,数据结构及算法,redis,skiplist,数据库,后端,数据结构,链表)