您好,欢迎访问一九零五行业门户网

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中有序集合的内部如何实现的详细内容。
其它类似信息

推荐信息