redis有序集合zset的底层实现——跳跃表skiplist

Redis 为什么这么快? Redis 的有序集合 zset 的底层实现原理是什么? —— 跳跃表 skiplist Redis有序集合 zset 的底层实现——跳跃表skiplist Redis简介 Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库、缓存和消息中间件。 它支持多种类型的数据结构,如字符串(Strings),散列(Hash),列表(List),集合(Set),有序集合(Sorted Set或者是ZSet)与范围查询,Bitmaps,Hyperloglogs 和地理空间... 阅读详情

何为跳表?

跳表是一个随机化的数据结构,实质就是一种可以进行二分查找的有序链表。

跳表在原有的有序链表上面增加了多级索引,通过索引来实现快速查找。

跳表不仅能提高搜索性能,同时也可以提高插入和删除操作的性能。

跳表详解

有序链表

考虑一个有序链表,我们要查找3、7、17这几个元素,我们只能从头开始遍历链表,直到查找到元素为止。

上述这个链表是有序的,但是不能使用二分查找,是不是很捉急?(P.S.数组可以实现二分查找)

那么,有没有什么方法可以实现有序链表的二分查找呢?

答案是肯定的,那就是我们将要介绍的这种数据结构——跳表。

跳表的演进

我们把一些节点从有序表中提取出来,缓存一级索引,就组成了下面这样的结构:

 

 

 现在,我们要查找17这个元素是不是要快很多呢?

我们只要从一级索引往后遍历即可,只需要经过1、6、15、17这几个元素就可以找到17了。

那么,我们要查找11这个元素呢?

我们从一级索引的1开始,向右到6,再向右发现是15,它比11大,此路不通,从6往下走,再从下面的6往右走,到7,再到11。

同样地,一级索引也可以往上再提取一层,组成二级索引,如下:

 

 

 这时候我们再查找17这个元素呢?

只需要经过6、15、17这几个元素就可以找到17了。

这基本上就是跳表的核心思想了,其实这也是一个“空间换时间”的算法,通过向上提取索引增加了查找的效率。

跳表的插入

上面讲的都是跳表的查询,那么,该如何向跳表中插入元素呢?

比如,我们要向上面这个跳表添加一个元素8。

首先,我们先根据投硬币的方式,决定8这个元素要占据的层数,没错就是扔硬币,是不是很好玩儿^^

比如,层数level=2。

然后,找到8这个元素在下面两层的前置节点。

接着,就是链表的插入元素操作了,比较简单。

最后,就像下面这样:

 

 

 

跳表的删除

查询、插入元素都讲了,下面我们就来说说怎么删除元素。

首先,找到各层中包含元素x的节点。

然后,使用标准的链表删除元素的方法删除即可。

比如,要删除17这个元素。

 

 

 

标准化的跳表

上面举的例子是完全随机的跳表,那么,如果我们每两个元素提取一个元素作为上一级的索引会怎么样呢?

 

 

 这是不是很像*衡二叉树,现在这颗树元素比较少,可能不太明显,我们来看个元素个数多的情况。

 

 

 可以看到,上一级元素的个数是下一级的一半,这样每次减少一半,就很接**衡二叉树了。

时间复杂度

我们知道单链表查询的时间复杂度为O(n),而插入、删除操作需要先找到对应的位置,所以插入、删除的时间复杂度也是O(n)。

那么,跳表的时间复杂度是多少呢?

如果按照标准的跳表来看的话,每一级索引减少k/2个元素(k为其下面一级索引的个数),那么整个跳表的高度就是(log n)。

学习过*衡二叉树的同学都知道,它的时间复杂度与树的高度成正比,即O(log n)。

所以,这里跳表的时间复杂度也是O(log n)。(这里不一步步推倒了,只要记住,查询时每次减少一半的元素的时间复杂度都是O(log n),比如二叉树的查找、二分法查找、归并排序、快速排序)

空间复杂度

我们还是以标准的跳表来分析,每两个元素向上提取一个元素,那么,最后额外需要的空间就是:

n/2 + n/(2^2) + n/(2^3) + ... + 8 + 4 + 2 = n - 2

所以,跳表的空间复杂度是O(n)。

总结

(1)跳表是可以实现二分查找的有序链表;

(2)每个元素插入时随机生成它的level;

(3)最低层包含所有的元素;

(4)如果一个元素出现在level(x),那么它肯定出现在x以下的level中;

(5)每个索引节点包含两个指针,一个向下,一个向右;

(6)跳表查询、插入、删除的时间复杂度为O(log n),与*衡二叉树接*;

 

redis作为一种内存KV数据库,提供了string, hash, list, set, zset等多种数据结构。其中有序集合zset在增删改查的性质上类似于C++ stl的map和Java的TreeMap,提供了一组“键-值”对,并且“键”按照“值”的顺序排序。但是与C++ stl或Java的红黑树实现不同的是,redis中有序集合的实现采用了另一种数据结构——跳跃表。跳跃表是有序单链表的一种改进,其查询、插入、删除也是O(logN)的时间复杂度。

跳跃表的原理

跳跃表的思想来自于一篇论文:Skip Lists: A Probabilistic Alternative to Balanced Trees. 如果想要深入了解跳跃表,可以阅读论文原文。这里引用论文中的一幅图对跳跃表的原理作一个简单的说明。

在这里插入图片描述

上图用a,b,c,d,e五种有序链表及其变式(变式的名字是我随便起的)说明了跳跃表的motivation.

  •    
  • [a]单链表:查询时间复杂度O(n)
  • [b]level-2单链表:每隔一个节点为一个level-2节点,每个level-2节点有2个后继指针,分别指向单链表中的下一个节点和下一个level-2节点。查询时间复杂度为O(n/2)
  • [c]level-3单链表:每隔一个节点为一个level-2节点,每隔4个节点为一个level-3节点,查询时间复杂度O(n/4)
  • [d]指数式单链表:每2^i个节点的level为i+1,查询时间复杂度为O(log2N)
  • [e]跳跃表:各个level的节点个数同指数式单链表,但出现的位置随机,查询复杂度仍然是O(log2N)吗

之所以这里关心查询复杂度,因为有序链表的插入和删除复杂度等于查询复杂度。

作为一种概率性算法,文章证明了跳跃表查询复杂度的期望是O(logN).

redis有序集合采用跳跃表的原因

为什么redis的有序集合采用跳跃表而不是红黑树呢?对于这个问题,可以在https://news.ycombinator.com/item?id=1171423找到作者本人的一个回答

  1. They are not very memory intensive. It’s up to you basically. Changing parameters about the probability of a node to have a given number of levels will make then less memory intensive than btrees.
  2. A sorted set is often target of many ZRANGE or ZREVRANGE operations, that is, traversing the skip list as a linked list. With this operation the cache locality of skip lists is at least as good as with other kind of balanced trees.
  3. They are simpler to implement, debug, and so forth. For instance thanks to the skip list simplicity I received a patch (already in Redis master) with augmented skip lists implementing ZRANK in O(log(N)). It required little changes to the code.

About the Append Only durability & speed, I don’t think it is a good idea to optimize Redis at cost of more code and more complexity for a use case that IMHO should be rare for the Redis target (fsync() at every command). Almost no one is using this feature even with ACID SQL databases, as the performance hint is big anyway.

About threads: our experience shows that Redis is mostly I/O bound. I’m using threads to serve things from Virtual Memory. The long term solution to exploit all the cores, assuming your link is so fast that you can saturate a single core, is running multiple instances of Redis (no locks, almost fully scalable linearly with number of cores), and using the “Redis Cluster” solution that I plan to develop in the future.

可以看到redis选择跳跃表而非红黑树作为有序集合实现方式的原因并非是基于并发上的考虑,因为redis是单线程的,选用跳跃表的原因仅仅是因为跳跃表的实现相较于红黑树更加简洁。

redis跳跃表的源码

跳跃表节点,跳跃表和zset结构体的定义在server.h

/* ZSETs use a specialized version of Skiplists */
typedef struct zskiplistNode {
    sds ele;
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        unsigned long span;
    } level[];
} zskiplistNode;

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

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

skiplist相关函数定义在t_zset.c中。跳跃表中,一个节点的level符合一定的概率,决定一个新增节点的level的函数是zslRandomLevel

/* Returns a random level for the new skiplist node we are going to create.
 * The return value of this function is between 1 and ZSKIPLIST_MAXLEVEL
 * (both inclusive), with a powerlaw-alike distribution where higher
 * levels are less likely to be returned. */
int zslRandomLevel(void) {
    int level = 1;
    while ((random()&0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
        level += 1;
    return (level<ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}

总结:

为什么Redis选择使用跳表而不是红黑树来实现有序集合?

首先,我们来分析下Redis的有序集合支持的操作:

1)插入元素

2)删除元素

3)查找元素

4)有序输出所有元素

5)查找区间内所有元素

其中,前4项红黑树都可以完成,且时间复杂度与跳表一致。

但是,最后一项,红黑树的效率就没有跳表高了。

在跳表中,要查找区间的元素,我们只要定位到两个区间端点在最低层级的位置,然后按顺序遍历元素就可以了,非常高效。

而红黑树只能定位到端点后,再从首位置开始每次都要查找后继节点,相对来说是比较耗时的。

此外,跳表实现起来很容易且易读,红黑树实现起来相对困难,所以Redis选择使用跳表来实现有序集合。

【Redis】拼多多面试官问我zset底层是如何实现的,我反手就把跳表的数据结构画了出

普通链表是一个节点一个节点按顺序的排序,而跳表是为每个节点随机出一个层数,每一层指向的节点可能会不同。
并且,越高层的链表节点数越少。这样查找的话,会从高层开始查找,一层一层往下找,最终在第一层找出其精准位置。
这样的查找方式可以跳过很多下层节点数,大大加快查找速度。
而对于插入和删除等,也只需要修改对应节点前后指针而已,这就比平衡树更有优势。

为什么采用跳表,而不使用哈希表或平衡树实现呢?
1、skiplist和各种平衡树(如AVL、红黑树等)的元素是有序排列的,而哈希表不是有序的。因此,在哈希表上只能做单个key的查找,不适宜做范围查找。所谓范围查找,指的是查找那些大小在指定的两个值之间的所有节点。
2、在做范围查找的时候,平衡树比skiplist操作要复杂。在平衡树上,我们找到指定范围的小值之后,还需要以中序遍历的顺序继续寻找其它不超过大值的节点。如果不对平衡树进行一定的改造,这里的中序遍历并不容易实现。而在skiplist上进行范围查找就非常简单,只需要在找到小值之后,对第1层链表进行若干步的遍历就可以实现。
3、平衡树的插入和删除操作可能引发子树的调整,逻辑复杂,而skiplist的插入和删除只需要修改相邻节点的指针,操作简单又快速。
4、从内存占用上来说,skiplist比平衡树更灵活一些。一般来说,平衡树每个节点包含2个指针(分别指向左右子树),而skiplist每个节点包含的指针数目平均为1/(1-p),具体取决于参数p的大小。如果像Redis里的实现一样,取p=1/4,那么平均每个节点包含1.33个指针,比平衡树更有优势。

REDIS - 跳跃表与压缩列表
【最完整系列】Redis-结构篇-压缩列表(压缩列表看这个)Redis的配置文件中关于有序集合底层实现的两个配置。
1、zset-max-ziplist-entries 128:zset采用压缩列表时,元素个数最大值。默认值为128。
2、zset-max-ziplist-value 64:zset采用压缩列表时,每个元素的字符串长度最大值。默认值为64。

当满足以下任一条件时,Redis便会将zset的底层实现由压缩列表转为跳跃表。
1、zset中元素个数大于zset_max_ziplist_entries;
2、插入元素的字符串长度大于zset_max_ziplist_value。
zset在转为跳跃表之后,即使元素被逐渐删除,也不会重新转为压缩列表。

压缩列表ziplist本质上就是一个字节数组,是Redis为了节约内存而设计的一种线性数据结构,可以包含多个元素,每个元素可以是一个字节数组或一个整数。

因为ziplist是紧凑存储,没有冗余空间,意味着新插入元素,就需要扩展内存:
1、分配新的内存,将原数据拷贝到新内存; 
2、扩展原有内存;
所以ziplist 不适合存储大型字符串,存储的元素也不宜过多。
 

C语言关键字static的绝妙用途 为什么要说static妙,它确实是妙,在软件开发或者单片机开发过程中,大家总以为static就是一个静态变量,在变量类型的前面加上就自动清0了,还有就是加上static关键字的,不管是变量还是关键字,在局部变量中,变量仅限于局部可见,在全局区中,static变量或函数仅限于本文件可见,当然还有一个重要的特性被忽略了。。。。       就是static修饰的局部变量 它的数值 是上一次函数调用结 阅读详情

相关推荐

英飞凌AURIX™ Development Studio(ADS)工程调试与烧录实战指南

本文详细介绍了英飞凌AURIX™ Development Studio(ADS)的工程调试与烧录实战指南。从调试环境搭建、硬件连接到断点设置、变量监控等核心调试技巧,帮助开发者快速掌握ADS安装使用教程,提升多核处理器开发效率。

k8l9m0n的博客 573

redis的数据结构zset---跳跃表

跳跃表是一种有序的数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。这么说,我们可能很难理解,我们可以先回忆一下链表。 一、复习跳跃表 1.1 什么是跳跃表 对于一个单链表来讲,即便链表中存储的数据是有序的,如果我们要想在其中查找某个数据,也只能从头到尾遍历链表。这样查找效率就会很低,时间复杂度会很高,是 O(n)。 如果我们想要提高其查找效率,可以考虑在链表上建索引的方式。每两个结点提取一个结点到上一级,我们把抽出来的那一级叫作索引。 这个时候,我们假设要查找节点8,

qq_33449307的博客 1546

Android开发必备:TBS腾讯浏览服务静态集成完整指南(附Demo下载)

本文详细解析了Android开发中TBS腾讯浏览服务的静态集成方案,通过对比动态集成,深入剖析了其核心原理与适用场景。文章提供了从环境准备、资源获取、项目配置到代码初始化的完整指南,并重点介绍了WebView与文件预览等高级特性的实战应用。针对集成过程中的常见问题,提供了详尽的排查清单与性能调优建议,旨在帮助开发者构建极致稳定、不依赖网络的WebView与文件预览功能。文末附有经过验证的Demo项目可供下载参考。

earth的博客 366

Redis(三):有序集合底层实现

跳跃表跳跃表的实现跳跃表结点层前进指针跨度后退指针分值和成员跳跃表重点 跳跃表 跳跃表是一种有序的数据结构,他通过在在每个结点中维护多个指向其他节点的指针,从而达到快速访问的目的。 跳跃表支持平均O(logN)O(logN)O(logN),最坏O(N)O(N)O(N)复杂度的节点查询,所以可以支持顺序性的操作批量去处理节点。 在大部分情况下,跳跃表的效率跟平衡树差不多,但实现起来比平衡树简单。 跳跃表是Redis中有序集合键的底层(也就是ZSet)。 Redis只在两个地方使用了跳跃表,一个是实现有序集合.

GDUT_Trim的博客 996

Android Profiler 帧率优化实战与性能调优

本文详细介绍了使用Android Profiler进行帧率优化与性能调优的实战方法。通过分析主线程状态、FPS曲线和渲染阶段耗时,精准定位卡顿根源,并提供减少过度绘制、优化绘制命令及改善资源使用的具体策略。文章结合电商、游戏等真实案例,帮助开发者有效解决卡顿问题,提升应用流畅度。

palm99的专栏 536

【深度学习驱动流体力学】Python流体力学Ansys Fluent

PyFluent 是一个将 Python 编程语言与 Ansys Fluent 流体动力学 (CFD) 仿真软件集成的工具。它允许用户通过 Python 脚本来控制和自动化 Fluent 中的仿真任务,实现从预处理、求解到后处理的全流程控制。PyFluent 结合了 Python 的灵活性和 Fluent 的强大功能,提供了一种高效且灵活的 CFD 仿真方法。PyFluent 是一个强大而灵活的工具,使用户能够通过 Python 脚本全面利用 Ansys Fluent 的功能。

源代码杀手的博客 3123

Redis中集合的底层实现原理

Redis中集合的底层实现原理

zhx3310228972的博客 1581

Redis~有序结合(ZSet)的数据结构之跳表(SkipList

之所以这样设置是因为考虑到如果直接使用跳跃表,如果需要查找成员的分值时只能通过遍历成员来进行查找,而这样的效率是O(logN)而字典虽然建立映射后可以O(1)的查找到分值,但是哈希表只能通过key值进行查找,并不支持范围查询。所以将两者进行结合,使用字典建立起元素与分值的映射,使用字典来进行成员分数的查找,而使用跳跃表来进行范围型操作,这样就很好的解决了这个问题。跳跃表介绍跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。

VIP129370的博客 1074

多算法数据预测——BP、ELM、LSTM、BiLSTM和SAELSTM,附Matlab源码

本文将为大家介绍基于BP、ELM、LSTM、BiLSTM和SAELSTM多种算法的数据预测,并提供相应的Matlab源码。SAELSTM算法是一种结合自动编码器和LSTM神经网络的深度学习方法,用于时间序列数据预测。ELM算法是一种单层前向神经网络,在单次训练过程中直接产生输出权重,从而具有快速学习和良好推广性能。多算法数据预测——BP、ELM、LSTM、BiLSTM和SAELSTM,附Matlab源码。总体来看,采用多种算法进行数据预测可以提高预测准确率,并可根据不同场景选择适合的算法。

qq_39605374的博客 861

STM32入门教程:WiFi通信

第四步:初始化串口 在生成的代码中,您可以找到一个名为 "USARTx_Init" 的函数,其中 "x" 是您选择的串口号。然后,我们使用 "AT+CIPSEND" 命令发送UDP数据,接收到服务器的回复,并在终端上显示收到的数据。在配置向导中,您可以选择启用USART串口功能,并根据您的硬件连接,将串口设置为与WiFi模块连接的串口。在上述代码中,我们使用了 "HAL_UART_Receive" 函数来接收串口数据,并使用 printf 来在终端上显示收到的数据。如果有任何问题,请随时向我提问。

2401_85258012的博客 1073

ZSet跳表和压缩列表原理

【Redis】拼多多面试官问我zset底层是如何实现的,我反手就把跳表的数据结构画了出来 总结: 普通链表是一个节点一个节点按顺序的排序,而跳表是为每个节点随机出一个层数,每一层指向的节点可能会不通过。 并且,越高层的链表节点数越少。这样查找的话,会从高层开始查找,一层一层往下找,最终在第一层找出其精准位置。 这样的查找方式可以跳过很多下层节点数,大大加快查找速度。 而对于插入和删除等,也只需要修改对应节点前后指针而已,这就比平衡树更有优势。 为什么采用跳表,而不使用哈希表或平衡树实现呢? 1、skipl

Hanyinh的博客 2414

如何使用Python爬取并保存网页上的所有附件

爬虫(Crawler)是一种自动化程序,它通过模拟人工访问网页并下载网页上的数据或文件,常用于数据采集和分析。爬虫通常以“爬取”的形式自动浏览和提取网页中的各种信息。本文详细介绍了如何使用Python爬取并保存网页中的附件文件,涵盖了网页解析、文件下载、多线程与异步优化等内容。希望通过本文的讲解,能够帮助你理解并掌握附件爬取的技巧。在实际应用中,爬虫开发不仅需要解决技术问题,还要遵守网络道德和法律法规,避免不当使用爬虫造成负面影响。

2201_76125261的博客 965

Redis 有序集合zset底层实现——ZipList (压缩表) 和 SkipList(跳跃表)

添加withscores ,输出zset的values 和 keys。zset底层由 ziplist 和 skiplist 实现。不加withscores ,只输出zset的values。zset是一个有序集合,zset的key不可重复。时,使用ziplist,否则使用skiplist。例: 从第一个遍历到最后一个。例:查询2到5分的player。例:查询2到5分的player。可以通过这个功能,实现搜索排名。例:统计符合2到5分总人数。

码鹿的记录 576

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Redis中ZSet的底层数据结构跳跃表skiplist,你真的了解吗?

欢迎大家关注我的微信公众号【老周聊架构】,Java后端主流技术栈的原理、源码分析、架构以及各种互联网高并发、高性能、高可用的解决方案。 一、前言 老周写这篇文章的初衷是这样的,之前项目中有大量使用 Redis 的 ZSet 数据结构来实现各种排行榜的功能。老周以前也写过关于跳表的数据结构,但那是纯数据结构方面来分析的,今天我们就来从跳跃表在 Redis 中的底层实现方向来分析。我们都知道 Redis 有五种常用的数据结构:String、Hash、List、Set 以及 ZSet,其中 ZSet 是 Re.

riemann_的博客 5023

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Redis中的zset原理以及用Java实现跳跃表

准备工作 (1)先在Redis官网下载最新的稳定版本6.2。按照官网给出的安装指南到Linux服务器上安装。 Redis源码 redis/src/server.c 文件定义了所有命令运行要调用的方法。zadd命令运行会调用t_zset.c文件的zaddCommand方法。 struct redisCommand redisCommandTable[] = { {"zadd",zaddCommand,-4, "write use-memory fast @sortedset", 0,NUL

liuffei的专栏 827

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

redis跳表——zset的底层实现

博客主页:🏆看看是李XX还是李歘歘🏆 🌺每天不定期分享一些包括但不限于计算机基础、算法、后端开发相关的知识点,以及职场小菜鸡的生活。🌺 💗点关注不迷路,总有一些📖知识点📖是你想要的💗 ⛽️今天的内容是 redis跳表——zset的底层实现 ⛽️💻💻💻 ​ redis的有序集合zset在增删改查的性质上类似于C++ stl的map和Java的TreeMap,提供了一组“键-值”对,并且“键”按照“值”的顺序排序。但是与C++ stl或Java的红黑树实现不同的是,redi...

分享包括但不限于计算机基础知识、数据结构与算法、Golang技术栈。年与时驰,意与日去,遂成枯落,多不接世,悲守穷庐,将复何及! 3686

平衡树:为什么Redis内部实现用跳跃表

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

华为云官方博客 1108

redis set 大量数据_面试必问 Redis数据结构底层原理Hash、Set、ZSet篇

点击关注上方“Java大厂面试官”,第一时间送达技术干货。阅读文本大概需要 8 分钟。前言前面已经讲了面试必问 Redis 数据结构底层原理String、List篇;链接如下:面试必问 Redis 数据结构底层原理String、List篇redis版本:6.0.6Hash 字典是什么听名称就知道很像Java中的HashMap,原理也有很多相似之处,但是Reids做了很多优化,Redis的...

weixin_42153801的博客 1227

Redis——跳跃表

Redis——跳跃表 一、跳跃表简介 跳跃表(skiplist)是一种随机化的数据结构,由William Pugh在论文《Skip lists: a probabilistic alternative to balanced trees》中提出,是一种可以与平衡树媲美的层次化链表结构——查找、删除、添加等操作都可以在对数...

weixin_41563161的博客 536

Redis五大数据类型——Zet有序集合

Redis五大数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sorted set:有序集合)。 一、介绍 Zset 是Set的一个升级版本,他在set的基础上增加了一个顺序属性,每个member成员都带有一个score分数( redis通过分数进行集合内成员的排序)。 有序集合的成员是唯一的,但分数(score)却可以重复 场景:很适合在打赏日榜、近一周收益这类场景中运用。应用排名模块比较多。 二、数据结构 底层使用两...

祝我飞黄腾达 2462

Redis Zset底层结构解析:ziplist与跳跃表的设计与切换

在开发高性能服务时,有序集合(Sorted Set)既要满足成员去重,又要支持按分数排序和范围查询,Redis的Zset正是解决这类需求的经典结构。其底层采用双编码方案:数据量小时使用ziplist压缩列表,以极致的内存密度存储短成员和小分数;数据量增大后则切换为跳跃表(skiplist)加哈希表的复合结构,保证O(logN)的查询、插入与排名计算效率。这种务实的设计在内存占用和操作性能之间取得平衡,广泛应用于排行榜、时间窗口、延迟队列等业务场景。理解Zset从ziplist到skiplist的转换机制、参

weixin_33416697的博客 214

redis内部数据结构(6)-skiplist

Redis里面使用skiplist是为了实现`sorted set`这种对外的数据结构。sorted set提供的操作非常丰富,可以满足非常多的应用场景。 我们将大体分成三个部分进行介绍: 介绍经典的skiplist数据结构,并进行简单的算法分析。这一部分的介绍,与Redis没有直接关系。我会尝试尽量使用通俗易懂的语言进行描述。 讨论Redis里的skipl...

洛阳城下逢公子 237

Redis核心数据结构【zset】【从入门到入坟】

该博客对Redis中SortSet结构的常用命令,底层数据结构以及应用场景进行了说明

at10090的博客 804

Redis跳跃表源码剖析:ZSET有序集合的底层结构

跳跃表(skiplist)是一种基于有序链表的多层索引数据结构,通过随机化层高在概率上保证 O(logN) 的查找、插入与删除效率。在 Redis 中,有序集合(ZSET)的底层核心结构正是跳跃表,配合 dict 实现 member 到 score 的快速映射。跳跃表节点内部的 level[] 数组由前进指针(forward)和跨度(span)构成:forward 负责在不同层快速跳跃定位,span 则记录跨越的节点距离,二者共同支撑起 ZRANK、ZRANGEBYSCORE 等命令的对数级性能。这种设计让

weixin_34005090的博客 190

Redis中的zset底层实现

Redis的zset底层实现通过ziplist和skiplist两种方式,以适应不同的使用场景。Ziplist适用于元素数量较少且长度较短的情况,而skiplist则适用于元素数量较多或长度较长的情况。这两种实现方式使得Redis的zset既能够高效地存储和检索元素,又能够快速地进行范围查询和排序操作。通过理解这些底层实现,我们可以更好地利用Redis的zset来解决实际问题。版权声明:本博客内容为原创,转载请保留原文链接及作者信息。参考文章。

ning的博客 1574
上一篇: 我们听到的TiDB到底是什么?!
下一篇: 解决Redis分布式锁业务代码超时致使锁失效问题
wrr-cat
博客等级 码龄9年 128粉丝 302原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值