这篇“Redis中有序集合的内部如何实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Redis中有序集合的内部如何实现”文章吧。
有序集合的内部实现
有序集合的内部实现有两种,分别是:压缩列表(ziplist)和跳跃表(skiplist)。接下来,我们分别进行详细的了解。
以压缩列表作为内部实现
当有序集合的元素个数小于zset-max-ziplist-entries
(默认为128个),并且每个元素成员的长度小于zset-max-ziplist-value
(默认为64字节)的时候,使用压缩列表作为有序集合的内部实现。
每个集合元素由两个紧挨在一起的两个压缩列表结点组成,其中第一个结点保存元素的成员,第二个结点保存元素的分支。压缩列表中的元素按照分数从小到大依次紧挨着排列,有效减少了内存空间的使用。
举个例子,我们使用zadd
命令创建一个以压缩列表为实现的有序集合:
127.0.0.1:6379> zadd one-more-zset 1 one 2 two 3 three(integer) 3127.0.0.1:6379> zrange one-more-zset 0 -11) "one"2) "two"3) "three"127.0.0.1:6379> object encoding one-more-zset"ziplist"
以跳跃表作为内部实现
当有序集合的元素个数大于等于zset-max-ziplist-entries
(默认为128个),或者每个元素成员的长度大于等于zset-max-ziplist-value
(默认为64字节)的时候,使用跳跃表作为有序集合的内部实现。
此时,在有序集合中其实包含了两个结构,一个是跳跃表,另一个是哈希表。
在跳跃表中,所有元素按照从小到大的顺序排列。跳跃表的结点中的object
指针指向元素成员的字符串对象,score
保存了元素的分数。通过跳跃表,Redis可以快速地对有序集合进行分数范围、排名等操作。
在哈希表中,为有序集合创建了一个从元素成员到元素分数的映射。键值对中的键指向元素成员的字符串对象,键值对中的值保存了元素的分数。通过哈希表,Redis可以快速查找指定元素的分数。
虽然有序集合同时使用跳跃表和哈希表,但是这两种数据结构都使用指针共享元素中的成员和分数,不会额外的内存浪费。
举个例子,我们使用zadd
命令创建一个以跳跃表为实现的有序集合:
127.0.0.1:6379> zadd one-more-zset 1 long-long-long-long-long-long-long-long-long-long-long-long-long-long(integer) 1127.0.0.1:6379> zrange one-more-zset 0 -11) "long-long-long-long-long-long-long-long-long-long-long-long-long-long"127.0.0.1:6379> object encoding one-more-zset"skiplist"
内部实现的转换
当一个有序集合是以压缩列表作为内部实现时,再向这个有序集合添加较长的元素成员,或向这个有序集合的元素个数过多时,那么这个有序集合就会转换为以跳跃表作为内部实现。但是,以跳跃表作为内部实现的有序集合不会转换为以压缩列表作为内部实现。
举个例子,我们先创建一个以压缩列表作为内部实现的有序集合:
127.0.0.1:6379> zadd one-more-zset 1 one 2 two 3 three(integer) 3127.0.0.1:6379> zrange one-more-zset 0 -11) "one"2) "two"3) "three"127.0.0.1:6379> object encoding one-more-zset"ziplist"
然后,再向它添加一个较长成员的元素,它就是转换为以跳跃表作为内部实现:
127.0.0.1:6379> zadd one-more-zset 4 long-long-long-long-long-long-long-long-long-long-long-long-long-long(integer) 1127.0.0.1:6379> zrange one-more-zset 0 -11) "one"2) "two"3) "three"4) "long-long-long-long-long-long-long-long-long-long-long-long-long-long"127.0.0.1:6379> object encoding one-more-zset"skiplist"
然后,再把那一个较长成员的元素从有序集合中移除,有序集合依然是以跳跃表作为内部实现:
127.0.0.1:6379> zrem one-more-zset long-long-long-long-long-long-long-long-long-long-long-long-long-long(integer) 1127.0.0.1:6379> zrange one-more-zset 0 -11) "one"2) "two"3) "three"127.0.0.1:6379> object encoding one-more-zset"skiplist"
以上就是关于“Redis中有序集合的内部如何实现”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。