Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Data structures 为什么Redis SortedSet使用跳过列表而不是平衡树?_Data Structures_Redis_Sortedset_Skip Lists - Fatal编程技术网

Data structures 为什么Redis SortedSet使用跳过列表而不是平衡树?

Data structures 为什么Redis SortedSet使用跳过列表而不是平衡树?,data-structures,redis,sortedset,skip-lists,Data Structures,Redis,Sortedset,Skip Lists,Redis文件如下所述: zset是使用两个数据结构保存相同元素的有序集 为了获得O(log(N))将操作插入和删除到排序的 数据结构 元素被添加到将Redis对象映射到的哈希表中 分数。同时将元素添加到跳过列表中 将分数映射到Redis对象(因此对象在 这一“观点”) 我不太明白。有人能给我一个详细的解释吗?首先,我想我了解了Redis文档的内容。Redis ordered set通过用户指定的元素分数来维护元素的顺序。但当用户使用某些Redis Zset API时,它只提供元素参数。例如:

Redis文件如下所述:

zset是使用两个数据结构保存相同元素的有序集 为了获得O(log(N))将操作插入和删除到排序的 数据结构

元素被添加到将Redis对象映射到的哈希表中 分数。同时将元素添加到跳过列表中 将分数映射到Redis对象(因此对象在 这一“观点”)


我不太明白。有人能给我一个详细的解释吗?

首先,我想我了解了Redis文档的内容。Redis ordered set通过用户指定的元素分数来维护元素的顺序。但当用户使用某些Redis Zset API时,它只提供元素参数。例如:

ZREM key member [member ...]
ZINCRBY key increment member
...
redis需要知道这个成员(元素)的值,所以它使用哈希表来维护映射,就像文档中说的:

元素被添加到将Redis对象映射到的哈希表中 得分

当它接收到一个成员时,它通过哈希表找到它的值,然后操作跳过列表上的操作以保持集合的顺序。redis使用两种数据结构来维护双重映射,以满足不同API的需要

我读了威廉·普格(William Pugh)的论文《跳过列表:概率论》(Skip List:A 替代平衡树,发现跳过列表非常优雅,比旋转更容易实现

另外,我认为一般的二叉平衡树能够在同时降低成本的情况下完成这项工作。如果我遗漏了什么,请指出。

安特里兹说,请参见

有几个原因:

  • 它们不是很占用内存。基本上由你决定。更改关于节点具有给定级别数的概率的参数将使其比btree占用更少的内存
  • 排序集通常是许多ZRANGE或ZREVRANGE操作的目标,即作为链表遍历跳过列表。通过此操作,跳过列表的缓存局部性至少与其他类型的平衡树一样好
  • 它们更易于实现、调试等。例如,由于跳过列表的简单性,我收到了一个补丁(已经在Redis master中),其中包含在O(log(N))中实现ZRANK的扩展跳过列表。它只需对代码进行少量更改。
关于仅附加的耐用性和速度,我不认为以更多代码和更复杂的用例为代价优化Redis是一个好主意,因为对于Redis目标来说IMHO应该是罕见的(每个命令都使用fsync()。几乎没有人使用这个特性,即使是在ACID-SQL数据库中,因为性能提示无论如何都很重要


关于线程:我们的经验表明Redis主要是I/O绑定的。我正在使用线程从虚拟内存提供服务。利用所有核心的长期解决方案是,假设您的链接速度如此之快,您可以使单个核心饱和,则运行多个Redis实例(无锁,几乎完全可随核心数线性扩展),并使用“Redis群集”我计划在未来开发的解决方案。

找出这些天结构提供的优点/缺点,也许你能够回答自己的问题。你没有注意到在跳过列表中检索第n项是O(log(n)),而在平衡树中检索第n项是O(n)。这对于ZRANK或ZRANGE命令非常有用。感谢您的帮助。我认为,如果我们在平衡树中维护每个节点的children\u count值,我们可以在中得到O(log(n))中的第n项bt@DidierSpezia为什么在平衡树中接收第n项是O(n)操作?难道树不能被设计成一个顺序统计树(每个节点都知道它的左、右子树的大小)以便找到第n个项变成O(logn)?@DidierSpezia和ZREVRANGE在rb-tr中不容易实现