redis使用skiplist跳表的原因解析

 更新时间:2022年10月13日 10:59:07   作者:bitcarmanlee  
经常会有人问这个问题,redis中为什么要使用跳表?这个问题,redis作者已经给出过明确答案,今天通过本文再给大家讲解下这个问题,对redis skiplist跳表知识感兴趣的朋友一起看看吧

1.什么是skiplist跳表

跳表是一种特殊的链表,特殊的点在于其可以进行二分查找。普通的链表要查找元素只能挨个遍历链表中的所有元素,而跳表则利用了空间换时间的策略,在原来有序链表的基础上面增加了多级索引,然后利用类似二分查找的思路来快速实现查找功能。跳表可以支持快速的查找,插入,删除等操作,时间复杂度为O(logn),空间复杂度为O(n)。

2.随机层数的计算

跳表在节点插入时候,会随机出一个层数,依靠这个随机数操作构建的多层链表结构,能保证一个比较好的查找性能。这个随机层数不是一个普通的服从均匀分布的随机数,具体的计算逻辑如下

1.首先,每个节点肯定都有第1层指针(每个节点都在第1层链表里)。
2.如果一个节点有第i层(i>=1)指针(即节点已经在第1层到第i层链表中),那么它有第(i+1)层指针的概率为p。
3.节点最大的层数不允许超过一个最大值,记为MaxLevel。

伪代码如下

randomLevel()
    level := 1
    // random()返回一个[0...1)的随机数
    while random() < p and level < MaxLevel do
        level := level + 1
    return level

randomLevel逻辑中包含有两个参数,一个是概率p,一个是最大层数MaxLevel。在redis的实现中,这两个参数分别为

p = 1/4
MaxLevel = 32

该部分内容来自于如下文档:

skiplist的算法性能分析

关于跳表本身更详细的讲解可以参考上述文档。

3.redis为什么要使用跳表

经常会有人问这个问题,redis中为什么要使用跳表?

这个问题,redis作者已经给出过明确答案

  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.

按照我自己的理解,稍微翻译一下就是
1.跳表不是非常吃内存,并且基本是取决于你自己。你可以通过改变参数p(第二部分中提到的),从而达到比btree消耗更少内存的目的。

2.redis中的zset结构经常会使用ZRANGE或者ZREVRANGE这种操作,这个时候遍历跳表就相当于遍历一个普通的链表。这种情况下,跳表的表现跟btree一样优秀。

3.很多人认为这一点是最重要的原因。跳表实现起来更容易,只需要一点点代码就能达到效果,修改起来也很方便。

到此这篇关于redis为什么要使用skiplist跳表的文章就介绍到这了,更多相关redis skiplist跳表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈Redis分布式锁的正确实现方式

    浅谈Redis分布式锁的正确实现方式

    这篇文章主要介绍了浅谈Redis分布式锁的正确实现方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • Redis本地/远程(外部)连接失败问题及解决

    Redis本地/远程(外部)连接失败问题及解决

    这篇文章主要介绍了Redis本地/远程(外部)连接失败问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • 分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了

    分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了

    Zookeeper的机制可以保证分布式锁实现业务代码简单,成本低,Redis如果要解决分布式锁的问题,对于一些复杂的情况,很难解决,成本较高,这篇文章重点给大家介绍分布式锁选择Zookeeper 而不是Redis的理由,一起看看吧
    2021-05-05
  • Redis超详细讲解高可用主从复制基础与哨兵模式方案

    Redis超详细讲解高可用主从复制基础与哨兵模式方案

    Redis因为其高性能和易用性在我们后端的服务中发挥了巨大的作用,并且很多重要功能的实现都会依赖redis,本篇我们来了解Redis高可用主从复制与哨兵模式
    2022-04-04
  • Spring Boot 中的 Redis 分布式锁

    Spring Boot 中的 Redis 分布式锁

    这篇文章主要介绍了Spring Boot 中的 Redis 分布式锁及,Redis分布式锁的优化需要的朋友可以参考下
    2023-10-10
  • Redis中三种特殊数据类型命令详解

    Redis中三种特殊数据类型命令详解

    Geospatial是地理位置类型,我们可以用来查询附近的人、计算两人之间的距离等,这篇文章主要介绍了Redis中三种特殊数据类型命令详解,需要的朋友可以参考下
    2024-05-05
  • redis单节点安装与配置方式

    redis单节点安装与配置方式

    这篇文章主要介绍了redis单节点安装与配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Redis类型type与编码encoding原理及使用示例

    Redis类型type与编码encoding原理及使用示例

    这篇文章主要为大家介绍了Redis类型type与编码encoding原理及使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 详解redis集群的三种方式

    详解redis集群的三种方式

    Redis三种集群方式分别是主从复制,哨兵模式,Cluster集群,这篇文章主要介绍了redis集群的三种方式,本文给大家介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • Redis模仿发送手机验证码功能

    Redis模仿发送手机验证码功能

    这篇文章主要介绍了Redis模仿手机验证码发送功能,通过示例代码给大家讲解通过用户输入手机号以及验证码进行校验,代码简单易懂,需要的朋友可以参考下
    2021-09-09

最新评论