为什么 Redis 使用 skiplist 来实现 zset
why Redis use skiplist to implement zset
研究Redis的实现,知道zset
后面有两个数据结构(skiplist
和ziplist
)。我知道 skiplist
的一些基本思想(保持多个指针以更快地访问下一个元素,搜索的平均时间复杂度为 O(logN))。
我的问题是:
我看资料说redis有两种情况会用skiplist
来实现zset
,第一种:zset中的成员很多,第二种:zset
中的成员很长[=17] =].
在这两种情况下使用skiplist
而不是ziplist
有什么好处,为什么这两种情况需要特殊处理?为什么我们不总是使用一种数据结构来实现zset
?
ziplist 的搜索和更新时间复杂度为 O(n),而 skiplist 的时间复杂度为 O(logN)
ziplist 的唯一好处是内存使用。由于zip list是线性内存地址实现的,没有指向其他节点的指针,因此可以为Redis节省大量内存space。
当你在zset中只有很少的成员时,O(N) 和O(logN) 不会有显着差异。但是内存使用会有很大的差异(考虑你有 1m 个 zset 键,每个 zset 只有 10 个成员)。
并且当zset中有很多成员时(比如1m),时间复杂度很重要,因为它会影响并发性能。
研究Redis的实现,知道zset
后面有两个数据结构(skiplist
和ziplist
)。我知道 skiplist
的一些基本思想(保持多个指针以更快地访问下一个元素,搜索的平均时间复杂度为 O(logN))。
我的问题是:
我看资料说redis有两种情况会用skiplist
来实现zset
,第一种:zset中的成员很多,第二种:zset
中的成员很长[=17] =].
在这两种情况下使用skiplist
而不是ziplist
有什么好处,为什么这两种情况需要特殊处理?为什么我们不总是使用一种数据结构来实现zset
?
ziplist 的搜索和更新时间复杂度为 O(n),而 skiplist 的时间复杂度为 O(logN)
ziplist 的唯一好处是内存使用。由于zip list是线性内存地址实现的,没有指向其他节点的指针,因此可以为Redis节省大量内存space。
当你在zset中只有很少的成员时,O(N) 和O(logN) 不会有显着差异。但是内存使用会有很大的差异(考虑你有 1m 个 zset 键,每个 zset 只有 10 个成员)。
并且当zset中有很多成员时(比如1m),时间复杂度很重要,因为它会影响并发性能。