摘要:Redis使用跳跃表(skiplist)作为有序集合(zset)的底层实现之一。

本文分享自华为云社区《5分钟了解Redis的内部实现跳跃表(skiplist)》,作者:万猫学社。

跳跃表简介

跳跃表(skiplist)是一个有序的数据结构,它通过在每个节点维护不同层次指向后续节点的指针,以达到快速访问指定节点的目的。跳跃表在查找指定节点时,平均时间复杂度为,最坏时间复杂度为O(N)。

Redis使用跳跃表(skiplist)作为有序集合(zset)的底层实现之一。当有序集合的元素个数大于等于zset-max-ziplist-entries(默认为128个),或者每个元素成员的长度大于等于zset-max-ziplist-value(默认为64字节)的时候,使用跳跃表和哈希表作为有序集合的内部实现。

举个例子,我们使用zadd命令创建一个以跳跃表为实现的有序集合:

127.0.0.1:6379> zadd one-more-zset 1 long-long-long-long-long-long-long-long-long-long-long-long-long-long
(integer) 1
127.0.0.1:6379> zrange one-more-zset 0 -1
1) "long-long-long-long-long-long-long-long-long-long-long-long-long-long"
127.0.0.1:6379> object encoding one-more-zset
"skiplist"

跳跃表的实现

在Redis中的跳跃表是由zskiplist结构表示的,zskiplist结构包含由多个跳跃表节点组成的双向链表,每一个跳跃表节点都保存着元素成员和对应的分钟。下面我们一个一个地详细了解一下。

zskiplist结构

跳跃表是由zskiplist结构表示的,它包含以下几个属性:

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

跳跃表节点的结构

跳跃表节点使用zskiplistNode结构表示,它包含以下几个属性:

  • level属性:表示层的数组,数组中每个项使用zskiplistLevel结构表示,它包含以下两个属性:
    • forward属性:指向位于表尾方向其他节点的指针。
    • span属性:当前节点到forward指向的节点跨越了多少个节点。
  • backward属性:指向当前节点的前一个节点的指针。
  • obj属性:指向元素成员的指针。
  • score属性:当前元素成员对应的分数。

图解跳跃表

说了这么多,都比较抽象不容易理解,我们来举个例子:

这就是一个跳跃表的内部结构,其中有4个元素,键分别是:万、猫、学、社。

为什么不使用平衡树?

跳跃表以有序的方式在层次化的链表中保存元素, 在大多数情况下,跳跃表的效率可以和平衡树媲美,查找、删除、添加等操作都可以在对数期望时间下完成, 并且比起平衡树来说, 跳跃表的实现要简单直观得多。所以在Redis中没有使用平衡树,而是使用了跳跃表。

点击关注,第一时间了解华为云新鲜技术~

平衡树:为什么Redis内部实现用跳跃表的更多相关文章

  1. Redis实现之字典跳跃表

    跳跃表 跳跃表是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.跳跃表支持平均O(logN).最坏O(N)的时间复杂度查找,还可以通过顺序性操作来批量处理节 ...

  2. Redis学习之zskiplist跳跃表源码分析

    跳跃表的定义 跳跃表是一种有序数据结构,它通过在每个结点中维持多个指向其他结点的指针,从而达到快速访问其他结点的目的 跳跃表的结构 关于跳跃表的学习请参考:https://www.jianshu.co ...

  3. 图解Redis之数据结构篇——跳跃表

    前言       跳跃表是一种有序的数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.这么说,我们可能很难理解,我们可以先回忆一下链表. 一.复习跳跃表 1.1 什么 ...

  4. Redis 底层数据结构之跳跃表

    文章参考 <Redis 设计与实现>黄建宏 Redis(2) 跳跃表 跳跃表 跳跃表 skiplist 是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节 ...

  5. 4.redis设计与实现--跳跃表

    1.跳跃表由两个结构体构成: 2.总结:

  6. 数据结构与算法简记--redis有序集合实现-跳跃表

    跳表 定义 为一个值有序的链表建立多级索引,比如每2个节点提取一个节点到上一级,我们把抽出来的那一级叫做索引或索引层.如下图所示,其中down表示down指针,指向下一级节点.以此类推,对于节点数为n ...

  7. redis 系列7 数据结构之跳跃表

    一.概述 跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.在大部分情况下,跳跃表的效率可以和平衡树(关系型数据库的索引就是平衡树 ...

  8. Redis底层探秘(二):链表和跳跃表

    链表简介 链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活地跳转链表的长度. 作为一种常用数据结构,链表内置在很多高级的编程语言里面,因为Redis使用C语言并没有内 ...

  9. Redis数据结构之跳跃表

    跳跃表是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的. 一.跳跃表结构定义1. 跳跃表节点结构定义: 2. 跳跃表结构定义: 示例: 二.跳跃表节点中各种 ...

随机推荐

  1. 从服务间的一次调用分析整个springcloud的调用过程(二)

    先看示例代码 @RestController @RequestMapping("/students") public class StudentController { @Auto ...

  2. Involuting Bunny! (2021.8)

      CF1555F & Submission.   Tags:「A.生成树」「B.Tricks」   分类处理询问的 trick:连接两个连通块的边显然合法,先用这些边构建生成森林.发现每条边 ...

  3. Solution -「JOISC 2019」「LOJ #3036」指定城市

    \(\mathcal{Description}\)   Link.   给定一棵含 \(n\) 个结点的树,双向边权不相同.\(q\) 次询问,每次询问在树上标记 \(e\) 个点,标记的价值为所有趋 ...

  4. Linux编译安装升级bash5.1

    线上服务器有次做漏洞扫描时,被扫描出有bash漏洞.平时还是比较少遇到有bash的漏洞,好在编译升级比较简单. 测试环境系统:CentOS.Ubuntu 一.下载官网最新bash版本 bash官网下载 ...

  5. Spring AOP应用之一:声明式事务

    所有数据访问技术都提供事务处理机制,这些技术提供了API用来开启事务.提交事务完成数据操作,或者在发生错误的时候回滚数据.Spring本身并不支持事务实现,同时只是负责提供标准接口来处理不同数据访问技 ...

  6. DDD-领域驱动设计简谈

    看到网上讨论 DDD 的文章越来越多,咱也不能甘于人后啊,以下是我对 DDD 的个人理解,短小精悍,不喜忽喷. 也谈DDD(领域驱动设计) 解决什么问题 传统模式,产品评审结束,开发人员就凭经验拆分模 ...

  7. 实战 | 关于随手一点就发现XSS漏洞这件事

    起因 今天正在做一个项目时,需要找一个云接码平台接码去登录系统.当我随手从百度找了一个接码平台时,一个偶然的发现,有了今天这篇文章. 正文 当我进入这个接码平台随便找了个手机号,然后等了好几分钟都没啥 ...

  8. [LeetCode]1431. 拥有最多糖果的孩子

    给你一个数组 candies 和一个整数 extraCandies ,其中 candies[i] 代表第 i 个孩子拥有的糖果数目. 对每一个孩子,检查是否存在一种方案,将额外的 extraCandi ...

  9. nginx 80端口强制转443

    server { listen 80; server_name test.com; rewrite ^(.*)$ https://${server_name}$1 permanent; } serve ...

  10. C#控制台输出瑞典、中文显、日语显示乱码问题

    问题:瑞典文字的"æ"在控制台中无法正确的显示? String[] strings1 = { "case", "encyclopædia", ...