redis为什么要使用skiplist跳表
Posted bitcarmanlee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
该部分内容来自于如下文档:
关于跳表本身更详细的讲解可以参考上述文档。
3.redis为什么要使用跳表
经常会有人问这个问题,redis中为什么要使用跳表?
这个问题,redis作者已经给出过明确答案
-
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.
-
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.
-
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跳表的主要内容,如果未能解决你的问题,请参考以下文章