整数集合(intset)是redis的集合(set)类型的一个encoding方式之一,如果set中值包含整数,并且元素较少的话,redis就会采用intset作为该类型的实现。
简单看一下整数集合(intset)的定义:
typedef struct intset { // 保存元素所使用的类型的长度 uint32_t encoding; // 元素个数 uint32_t length; // 保存元素的数组 int8_t contents[]; } intset;
由定义可以看出,intset中元素是保存在数组contents中的,也就是说它在结构上是有序的。contents中的元素不重复且各元素在其中由小到大排列。在对contents中的元素进行读取或者写入时,程序并不是直接使用contents来对元素进行索引,而是根据encoding的值,对contents进行类型转换和指针运算,计算出元素在内存中的正确位置。在添加新元素,进行内存分配时,分配的空间也是由encoding的值决定。
之前提到,采用intset有一个先决条件就是元素较少,那何以为少呢?与ziplist类似,intset也有相关的配置项:
set-max-intset-entries 512
也就是说,只要保证set中整数的个数小于设定的数量,那Redis就会采用intset来降低内存的使用。以下的代码示例展示了这一点:
>>> import redis >>> conn = redis.Redis() >>> conn.sadd('set-object', *range(500)) 500 >>> conn.debug_object('set-object') {'encoding': 'intset', 'refcount': 1, 'lru_seconds_idle': 10, 'lru': 334651, 'at': '009facf4', 'serializedlength': 1010, 'type': 'Value'} >>> conn.sadd('set-object', *range(500, 1000)) 500 >>> conn.debug_object('set-object') {'encoding': 'hashtable', 'refcount': 1, 'lru_seconds_idle': 10, 'lru': 334652, 'at': '009facf4', 'serializedlength': 2874, 'type': 'Value'}
另外,一些参考资料值得去更多的研究一下: