2012-09-04 41 views
3

redis中排序集和列表之间的空间有什么区别?我的猜测是有序集是某种平衡的二叉树,列表是链表。这意味着,除了我为它们中的每一个编码的三个值之外,关键点,分数,值,尽管我会将链接列表的分数和值合并在一起,但开销是链接列表需要跟踪一个其他节点,并且二叉树需要跟踪两个,因此使用有序集合的空间开销为O(N)。Redis数据结构空间需求

如果我的值和得分都是长整数,并且指向其他节点的指针也是长整型,那么单个节点的空间开销似乎在64位计算机上从3个长变为4个long,空间增加了33%。

这是真的吗?

+0

关于[redis内存优化文档](http://redis.io/topics/memory-optimization)有很多关于此的信息,热烈推荐阅读。我不确定您是否建议使用列表作为临时排序集?当然不是。 –

+0

@LinusGThiel我读了关于内存优化的redis文档,它没有提到排序的集合和列表,除非说如果他们很小就可以使用ziplists。我几乎肯定会使用列表作为临时排序集合,因为我的“分数”是一个时间戳,所以我可以推动并维护排序顺序。 – nnythm

+0

好的,只需要知道从列表/排序集的不同部分检索时的时间复杂性。如果你在这里没有得到很好的答案,我建议你将这个问题引导到邮件列表,这些邮件列表通常非常了解和包容。 –

回答

5

它远远超过您的估计。我们假设没有使用ziplists(即你有很多项目)。

Redis列表是一个经典的双链表:每个项目3个指针(prev,next,value)。

排序集是一个字典加上一个跳过列表。在字典中,项目也将存储3个指针(键值,下一个)。跳过列表内存占用比较复杂:每个节点需要1个双倍(分数),2个指针(obj,向后),再加上n个耦合(指针,跨度值),n在1和32之间。大多数项目只需要1或2对夫妇。

换句话说,当它没有被表示为一个ziplist时,到目前为止,排序集合是开销最大的Redis数据结构。与列表相比,内存开销超过200%(即3倍)。

注意:使用Redis评估内存消耗的最佳方法是尝试使用伪数据构建大型列表或排序集并使用INFO来获取内存占用量。

+0

嘿,我必须误解info命令的输出。我做了redis-benchmark -q -n 1000000 zadd sortedset rand:00000000000 ele:rand:000000000000,然后在redis-cli中调用命令INFO,并获得1.30M的used_memory_peak_human。但是,我正在做一百万个有序集添加,因此显然必须有超过一兆字节的数据。我错过了什么? – nnythm

+0

几个问题:分数应该是一个数字(这不是因为rand前缀),有序集保证了唯一性(所以你需要随机化键 - 参见redis-benchmark的-r选项) –

+0

使用./redis -benchmark -q -r 10000000000 -n 1000000 zadd排序集0 ele:rand:000000000000,我为1M项目获得135 MB。 –