美文网首页
(Redis篇-5)- Redis的跳表?

(Redis篇-5)- Redis的跳表?

作者: Burlong | 来源:发表于2021-09-11 00:50 被阅读0次

redis使用跳跃表作为有序集合键的底层实现之一,当一个有序集合包含的元素数量比较多时,redis会使用跳表结构对查询效率进行优化。

与常规链表的不同之处

redis的跳表与常规跳表不同的地方在于

  • score值可以重复,即多个不同member可以存储相同的score值,因此确定一个元素需要检查score和member
  • 每个节点会携带一个后退指针

redis中的跳表两个关键struct-结构体

1、zskipList

c语言代码示例:

typedef struct zskiplist {

    // 头节点,尾节点
    struct zskiplistNode *header, *tail;

    // 节点数量
    unsigned long length;

    // 目前表内节点的最大层数
    int level;

} zskiplist;

属性:

  • header:头指针
  • tail:尾指针
  • evel:记录当前跳表中所有节点中最大的层数。
  • length:记录跳表长度,即节点数量(注意,不包含表头节点)

2、zskiplistNode

c语言代码示例:

typedef struct zskiplistNode {

    // member 对象
    robj *obj;

    // 分值
    double score;

    // 后退指针
    struct zskiplistNode *backward;

    // 层
    struct zskiplistLevel {

        // 前进指针
        struct zskiplistNode *forward;

        // 这个层跨越的节点数量
        unsigned int span;

    } level[];

} zskiplistNode;

属性:

  • 层(levelN)

    1、L1、L2。。LN表示第N层,每一层都会带两个属性:前进指针与跨度。前进指针指向后面的其他节点,而跨度则表示离后面节点的距离。如第一张图中的箭头,表示前进指针,上面的数字则是跨度。

    2、在创建一个新跳表时,程序会根据幂次定律(powerlaw,越大的数出现的概率越小)随机生成一个介于1~32的值作为level数组大小,这个大小就是层的“高度”。

  • 后退指针(backward)

    每个节点维护一个后退指针,因只有一个指针,意味着节点最多一次只能后退一个节点。(个人理解,由于一个节点会有多个指向后续节点的指针,但只有一个后退指针,所以不可认为是双向链表。)

  • 分值(score)

    各个节点根据该值进行排序

  • 成员对象(obj)

    节点所存的成员对象。在同个跳表中,各节点存的成员对象必须唯一,但不同节点可以保存相同的分值score(意味着匹配节点时除了匹配score还要匹配对象),在分值相同时,会比较对象大小,小的排在前面。


两个数据结构的各个API的时间复杂度一览

image.png

应用

redis中跳表唯一的应用就是用来实现有序集数据类型。

如下,创建一个带3个元素的有序集:

redis> ZADD s 6 x 10 y 15 z
(integer) 3

redis> ZRANGE s 0 -1 WITHSCORES
1) "x"
2) "6"
3) "y"
4) "10"
5) "z"
6) "15"

在redis中则会映射出这样一个跳表

image.png

注:图中的score值实际只存储了指针,由于要跟另一个实现有序集的结构(字典)分享,真实值是不存储于节点中的。

总结:

  • redis跳表基于单链表加索引的数据结构进行实现,本质上是空间换时间
  • 指在有序集合节点元素较大或者元素较多时会用跳表实现
  • 两个核心数据结构:zskiplist和zskipnode
  • redis每个跳跃表节点层高在1~32之间
  • 不同节点分值可以相同,但对象必然不同,因此在查找匹配对象时,除了匹配score还要匹配对象。

参考:

Redis数据结构--跳跃表

相关文章

  • (Redis篇-5)- Redis的跳表?

    redis使用跳跃表作为有序集合键的底层实现之一,当一个有序集合包含的元素数量比较多时,redis会使用跳表结构对...

  • 2.跳表的基本实现和特性

    一、跳表 跳表的设计与实现为啥 redis 使用跳表(skiplist)而不是使用 red-black redis...

  • 【每日面试】微店二面面经分享

    springboot自动装配 redis跳表以及为什么要用跳表 redis你都用来干什么(说了缓存和分布式锁) r...

  • 跳表

    跳表的基本结构: Redis为什么使用跳表实现有序集合? 1.redis的有序集合中有一个很重要的操作是,按照区间...

  • Redis 跳表

    Redis为什么用跳表而不用平衡树? Redis里面使用skiplist是为了实现sorted set这种对外的数...

  • Redis 跳表

    跳跃表 跳跃表是一种有序的数据结构,通过在每个节点查找,还可以通过顺序性操作来批处理节点。跳跃表的效率可以和平衡树...

  • Redis为什么用跳表而不用平衡树?

    Redis为什么用跳表而不用平衡树? 本文是《Redis内部数据结构详解》系列的第六篇。在本文中,我们围绕一个Re...

  • redis为啥这么快

    redis为啥这么快 基于内存 底层使用了优秀的数结构如哈希表、跳表 io多路复用,使用epoll模式 redis...

  • redis 跳表(6)

    跳表(skiplist)是一个特俗的链表,相比一般的链表,有更高的查找效率,其效率可比拟于二叉查找树总结跳表的性质...

  • Redis:跳表SkipList

    原文链接:SkipList 跳表 为什么选择跳表 目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay...

网友评论

      本文标题:(Redis篇-5)- Redis的跳表?

      本文链接:https://www.haomeiwen.com/subject/ypjowltx.html