- 浏览: 142436 次
文章分类
最新评论
前提申明,因篇幅有限,本文只介绍跳跃表在 Redis 中的应用,而关于跳跃表的原理性介绍,还请参考其他相关书籍,或参考博文跳跃表 SkipList【数据结构】原理及实现。
跳跃表是一种有序数据结构,它实现了同二分查找一样的平均 O(logN)、最坏 O(N) 复杂度的节点查找。由于它的效率可以和平衡树相媲美,而实现又比平衡树简单,因此很多情况下可以用来代替平衡树。
跳跃表在 Redis 中不如链表和字典等数据结构的应用广泛,只有两个地方用到。一是实现有序集合键,另一个是在集群节点中用作内部数据结构。
Redis 中的跳跃表节点的实现如下:
关于该结构中的成员需要作如下说明:
* 层数组 level:其中的每个 zskiplistLevel 结构元素都表示一层,该结构中包含一个指向同层中下一个链表节点的指针 forward,称为前进指针,以及一个称为跨度的属性 span,表示前进指针指向的下一个节点与当前节点的距离。跨度主要是用来计算目标节点的排位(rank,即相当于在底层整个有序链表中的索引位置):在查找某个节点的过程中,将沿途访问过的所有层的跨度累计起来,得到的结果就是目标节点在跳跃表中的排位。层就如同于对一个普通有序链表建立起了多级索引,所以一般层的数量越多,访问相应节点的速度就越快。每次创建一个新跳跃表节点的时候,Redis 都会根据幂次定律(即越大的数出现的概率越小)随机生成一个介于 1 到 32 之间的数作为 level 数组的大小,也就是层的“高度”。
* 后退指针 backward:主要用于从表尾向表头方向访问节点。它不能像前进指针一样可以一次跳过多个中间节点,因为每个节点只有一个后退指针,所以每次只能后退至前一个节点。
* 成员分值 score 和成员对象 obj:这两个属性就是每个节点中保存的真正的数据值。跳跃表中的所有节点都按分值从小到大来排序。成员分值可以相同,但成员对象必须唯一:分值相同的成员将按照成员对象的字典序来进行排序。
虽然通过多个跳跃表节点就可以组成一个跳跃表,不过 Redis 使用了如下的 zskiplist 结构来持有这些节点,这样就能更方便地对整个跳跃表进行处理,比如快速访问跳跃表的表头节点和表尾节点,或者快速地获取跳跃表的节点数量等。
下图是 Redis 中的一个跳跃表示例。
图中的 L1、L2 等字样表示节点的各个层,连线上带有数字的箭头代表前进指针,而那个数字就是跨度,后退指针用 BW 字样表示。另外,由于表头节点的后退指针、成员分值和成员对象都不会被用到,所以图中只显示了表头节点的各个层。
跳跃表是一种有序数据结构,它实现了同二分查找一样的平均 O(logN)、最坏 O(N) 复杂度的节点查找。由于它的效率可以和平衡树相媲美,而实现又比平衡树简单,因此很多情况下可以用来代替平衡树。
跳跃表在 Redis 中不如链表和字典等数据结构的应用广泛,只有两个地方用到。一是实现有序集合键,另一个是在集群节点中用作内部数据结构。
Redis 中的跳跃表节点的实现如下:
typedef struct zskiplistNode{ struct zskiplistLevel{ // 层数组 struct zskiplistNode *forward; // 前进指针 unsigned int span; // 跨度 }level[]; struct zskiplistNode *backward; // 后退指针 double score; // 成员分数 robj *obj; // 成员对象 }zskiplistNode;
关于该结构中的成员需要作如下说明:
* 层数组 level:其中的每个 zskiplistLevel 结构元素都表示一层,该结构中包含一个指向同层中下一个链表节点的指针 forward,称为前进指针,以及一个称为跨度的属性 span,表示前进指针指向的下一个节点与当前节点的距离。跨度主要是用来计算目标节点的排位(rank,即相当于在底层整个有序链表中的索引位置):在查找某个节点的过程中,将沿途访问过的所有层的跨度累计起来,得到的结果就是目标节点在跳跃表中的排位。层就如同于对一个普通有序链表建立起了多级索引,所以一般层的数量越多,访问相应节点的速度就越快。每次创建一个新跳跃表节点的时候,Redis 都会根据幂次定律(即越大的数出现的概率越小)随机生成一个介于 1 到 32 之间的数作为 level 数组的大小,也就是层的“高度”。
* 后退指针 backward:主要用于从表尾向表头方向访问节点。它不能像前进指针一样可以一次跳过多个中间节点,因为每个节点只有一个后退指针,所以每次只能后退至前一个节点。
* 成员分值 score 和成员对象 obj:这两个属性就是每个节点中保存的真正的数据值。跳跃表中的所有节点都按分值从小到大来排序。成员分值可以相同,但成员对象必须唯一:分值相同的成员将按照成员对象的字典序来进行排序。
虽然通过多个跳跃表节点就可以组成一个跳跃表,不过 Redis 使用了如下的 zskiplist 结构来持有这些节点,这样就能更方便地对整个跳跃表进行处理,比如快速访问跳跃表的表头节点和表尾节点,或者快速地获取跳跃表的节点数量等。
typedef struct zskiplist{ struct zskiplistNode *header, *tail; // 表头节点和表尾节点指针 unsigned long length; // 节点的数量 int level; // 节点的最大层数(表头节点的层数不计算在内) }zskiplist;
下图是 Redis 中的一个跳跃表示例。
图中的 L1、L2 等字样表示节点的各个层,连线上带有数字的箭头代表前进指针,而那个数字就是跨度,后退指针用 BW 字样表示。另外,由于表头节点的后退指针、成员分值和成员对象都不会被用到,所以图中只显示了表头节点的各个层。
发表评论
-
Lua 脚本
2019-10-07 19:49 687Redis 2.6 版本开始引入对 Lua 脚 ... -
Redis事务的实现
2019-09-22 18:56 472Redis 事务是 ... -
Redis集群之复制、故障转移及消息实现
2019-09-14 21:04 503在Redis集群 ... -
Redis集群实现原理
2019-09-14 12:19 679Redis 集群是 Redis 提供的分布式数 ... -
sentinel 系统介绍
2019-08-04 18:35 504Sentinel(哨兵)是 Redis 的高可 ... -
数据库复制
2019-07-13 22:02 368在连接到一 ... -
redis 客户端实现
2019-06-02 15:06 375Redis 服务器是典型的一对多服务器程序,通 ... -
AOF 持久化
2019-05-12 13:36 417除了前面提到的 RDB 持久化功能外,Redi ... -
RDB 文件结构
2019-04-27 12:10 581在RDB 持久化一节中,我们对 RDB 持久化 ... -
RDB 持久化
2019-04-14 17:20 421RDB 持久化功能可以将 Redis 在某个时 ... -
Redis 数据库通知功能的实现
2019-04-07 11:56 1287Reids 数据库通知功能可以让客户端通过订阅 ... -
数据库实现
2019-03-24 13:58 445Redis 服务器将其所有的数据库都保存在 r ... -
Redis 五种对象
2019-01-20 11:13 365阅读本节前需要阅读 Redis 对象系统概览一 ... -
Redis 对象系统概览
2019-01-06 13:10 783前面介绍了 Redis 中用到的所有主要数据结 ... -
整数集合与压缩列表
2018-12-09 21:19 593在 Redis 中,当一 ... -
字典实现
2018-08-20 15:49 569字典在 Redis 中的应用相当广泛,如 Redis ... -
redis 字符串和列表实现
2018-08-08 16:41 750Redis 虽说由 C 语言 ...
相关推荐
本篇将详细介绍跳跃表的原理、实现及其在Redis中的应用。 跳跃表由一系列层构成,每一层都是一个有序链表。从底层到顶层,链表中的节点数量逐渐减少,但跨度增加。最底层的链表包含所有元素,而顶层的链表可能只...
本篇将深入探讨跳跃表的基本概念、工作原理以及其在Redis中的应用。 ### 跃表的概念 跳跃表是由William Pugh于1989年提出的,它是一种随机化的数据结构,主要用于实现高效查找、插入和删除操作。与传统的平衡树如...
- **跳跃表的应用**:跳跃表在Redis中用于实现有序集合数据类型,支持元素的快速查找、插入和删除操作。 - **小结**:跳跃表结合了链表和二叉搜索树的优点,为Redis提供了高效的有序集合管理。 #### 二、内存映射...
Redis是一种高性能的键值对数据存储系统,常用于数据库、缓存和消息中间件等场景。Windows版本的Redis 3.2是针对Windows操作系统...通过理解并熟练运用这些知识点,开发者可以在Windows环境中轻松构建基于Redis的应用。
跳跃表是一种可以用来替代平衡树的数据结构,它通过在基本链表的基础上增加了多层索引以加快搜索、...跳跃表虽然在某些情况下无法达到完全平衡树的性能,但是其编程实现的简易性和灵活性使其成为许多实际应用中的选择。
Redis是一款开源、高性能的键值对存储系统,常用于数据缓存、消息队列和数据库等领域。本资源包含了Redis操作的源...通过学习和实践这些代码,开发者可以更好地理解和掌握Redis的使用,提升在实际项目中的应用能力。
2. 跳跃表(Skip List):Redis使用跳跃表来实现有序集合的高效查找。跳跃表是一种随机化数据结构,通过多层索引来加速查找过程,性能接近于平衡二叉搜索树,但实现起来更简单。 3. 哈希表(Hash Table):Redis的...
- **Skiplist**:对于更大规模的数据,Redis采用Skiplist(跳跃表)进行编码,这是一种随机化数据结构,通过在每个节点中维护多个指向其他节点的指针,达到快速访问节点的目的。跳跃表的平均时间复杂度为O(log N),...
为了提高读写效率,Redis还提供了多种数据结构优化手段,如压缩表、字典的负载因子调整、跳跃表等。此外,Redis支持主从复制,可以创建多个从节点来分摊读取压力,实现高可用性。当主节点出现故障时,可以自动或手动...
例如,链表、跳跃表(用于有序集合的快速查找)和压缩表(用于节省内存)等都是Redis内部的重要组件。 3. 源码编译与配置: 要在Windows上编译Redis源码,首先需要安装GCC编译器(如MinGW)和make工具。然后,使用...
- **用途:** 跳跃表允许 Redis 以 O(log N) 的时间复杂度进行成员的查找、插入和删除操作。 - **特点:** 与平衡二叉树相比,跳跃表更容易实现并且具有更好的性能表现。 #### 二、内存映射数据结构 **2.1 整数集合*...
跳跃表在Redis中的主要应用是实现有序集合数据类型。有序集合可以看作是一个不允许重复成员的集合,其中每个成员都有一个分数(score)与其关联,通过分数对成员进行排序。 **小结** 跳跃表作为一种高效的数据结构,...
Redis 是一个高性能的键值对数据库,以其丰富的数据结构、高效的数据操作以及广泛的应用场景而闻名。本资源提供了带有完整注释的 Redis 源代码,对于深入理解 Redis 内部工作原理、优化性能以及进行二次开发具有极大...
2. **有序集合的跳跃列表实现**:在3.2版本之前,有序集合(Sorted Set)使用了哈希表和跳跃表的混合结构,而3.2版本开始完全使用跳跃表,这提高了插入、删除和范围查询的性能。 3. **Lua脚本的改进**:Redis支持...
Redis是世界上最受欢迎的开源内存数据结构存储系统,它可以用作数据库、缓存和消息代理。...利用这个包,用户可以在Windows环境下搭建和管理自己的Redis服务,利用其丰富的数据结构和高性能特性满足各种应用场景。
Redis内部采用了多种高效的数据结构来存储数据,包括但不限于简单动态字符串(SDS)、链表、跳跃表和字典等。这些数据结构的选择是为了提高Redis的性能和效率。 - **简单动态字符串(SDS)**:用于替代C语言标准库中的...
在有序集合元素较多时,Redis会选择跳跃表作为底层实现。 5. 整数集合(Intset):整数集合使用动态编码,根据存储的整数大小自动调整,以节省内存。它可以存储16位、32位和64位整数,随着数据的变化,集合会进行...
Redis的源码主要由C语言编写,通过阅读源码,可以深入理解其内部数据结构(如哈希表、跳跃表)、网络通信机制以及集群通信协议。Jedis的源码则使用Java编写,提供了丰富的API接口,通过分析源码,我们可以学习如何...
总结来说,MIT算法导论公开课中的跳跃表章节深入浅出地介绍了这一高效的数据结构,让学习者能够理解其工作原理,并掌握如何在实际问题中运用。通过学习跳跃表,我们可以提高解决大规模数据处理问题的能力,尤其是在...