Redis阅读笔记-集合对象

Redis阅读笔记-集合对象

​ 集合对象的编码可以是intset或hashtable。

​ intset编码的集合对象使用整数集合作为底层实现, 集合对象包含的所有元素都被保存再整数集合里。

​ 举个例子, 以下代码将创建如下所示的intset编码集合对象:

127.0.0.1:6379> sadd numbers 1 3 5
(integer) 3
redisObject
type
REDIS_SET
encoding
REDIS_ENCODING_INTSET
ptr intset
... encoding
INTSET_ENC_INT16
length
3
contents 1 3 5

​ 另一方面, hashtable编码的集合对象使用字典作为底层实现, 字典的每个键都是一个字符串对象, 每个字符串对象包含了一个集合元素,而字典的值全部被设置为NULL。

​ 举个例子, 以下代码将创建如下图所示的hashtable编码集合对象:

127.0.0.1:6379> sadd fruits "apple" "banana" "cherry"
(integer) 3
redisObject
type
REDIS_SET
encoding
REDIS_ENCODING_HT
ptr dict
... StringObject
"cherry"
NULL
StringObject
"apple"
NULL
StringObject
"banana"
NULL

编码的转换

​ 当集合对象可以同时满足以下两个条件时, 对象使用intset编码:

  • 集合对象保存的所有元素都是整数值;
  • 集合对象保存的元素数据不超过512个

​ 不能满足这两个条件的集合对象需要使用hashtable编码。

注意

​ 这两个条件的上限值是可以修改的,具体请看配置文件中关于set-max-intset-entries选项的说明。

​ 对于使用intset编码的集合对象来说, 当使用intset编码所需的两个条件的任意一个不能被满足时, 就会执行对象的编码转换操作,原本保存再整数集合中的所有元素都会被转移并保存到字典里, 并且对象的编码也会从intset变为hashtable。

​ 举个例子,以下代码创建了一个只包含整数元素的集合对象, 该对象的编码为intset:

127.0.0.1:6379> sadd numbers 1 3 5
(integer) 3
127.0.0.1:6379> object encoding numbers
"intset"

​ 不过,只要我们向这个只包含整数元素的集合对象添加一个字符串元素, 集合对象的编码转移操作就会被执行:

127.0.0.1:6379> sadd numbers "seven"
(integer) 1
127.0.0.1:6379> object encoding numbers
"hashtable"

​ 除此之外, 若我们创建一个包含了512个整数元素的集合对象, 那么对象的编码应该时intset:

127.0.0.1:6379> eval "for i=1, 512 do redis.call('SADD', KEYS[1], i) end" 1 integers
(nil)
127.0.0.1:6379> scard integers
(integer) 512
127.0.0.1:6379> object encoding integers
"intset"

​ 但是,只要再向集合添加一个新的整数元素, 使得这个结合的元素变成513, 那么对象的编码转换操作就会被执行:

127.0.0.1:6379> sadd integers 10086
(integer) 1
127.0.0.1:6379> scard integers
(integer) 513
127.0.0.1:6379> object encoding integers
"hashtable"

posted @ 2020-10-09 17:22  phper-liunian  阅读(81)  评论(0编辑  收藏  举报