对象
redis的对象系统实现了基于引用计数技术的内存回收机制,当程序不再使用某个对象的时候,这个对象所占用的内存就会被自动释放。
redis通过引用计数技术实现了对象共享机制,这一机制可以在适当的条件下,通过让多个数据库键共享同一个对象来节约内存。
redis对象带有访问时间记录信息,可以计算数据库键的空转时长,在服务器启用了maxmemory功能情况下,空转时长大的键可能会被有限删除。
redisObject
typedef struct redisObject {
//类型:指定对象的类型
unsigned type:4;
//编码
unsigned encoding:4;
//指向底层实现数据结构的指针
void ptr;
//redis对象的引用计数信息,如果引用为0时会被释放。
int refcount;
//记录了对象最后一次被命令程序访问的时间
unsigned lru:22;
//
} robj ;
- 类型:type
type key
对象 | 对象type属性的值 | type命令的输出 |
---|---|---|
字符串对象 | REDIS_STRING | “string” |
列表对象 | REDIS_LIST | “list” |
哈希对象 | REDIS_HASH | “hash” |
集合对象 | REDIS_SET | “set” |
有序结合对象 | REDIS_ZSET | “zset” |
-
编码和底层实现:
object encoding key
编码常量 编码所对应的底层数据结构 REDIS_ENCODING_INT long类型的整数 REDIS_ENCODING_EMBSTR embstr编码的SDS REDIS_ENCODING_RAW SDS REDIS_ENCODING_HT 字典 REDIS_ENCODING_LINKEDLIST 双端链表 REDIS_ENCODING_ZIPLIST 压缩列表 REDIS_ENCODING_INTSET 整数结合 REDIS_ENCODING_SKIPLIST 跳跃表和字典
对象共享
通过object refcount A
查看键A所指向对象的引用计数。只有字符串对象是共享的。
对象空转时长
redisObject中的 lru属性,记录了对象最后一次被命令程序访问的时间。使用object idletime
可以打印出给定键的空转时长,即当前时间减去lru时间。这个命令不会修改lru属性。
字符串对象(string)
-
int
字符串对象保存的是long类型的整数值,会将整数值保存在ptr属性中(浮点数是使用字符串来保存的,即SDS)。
-
embstr
字符串对象保存的是一个字符串值,并且这个字符串的长度<=32字节。也是使用SDS来保存字符串。
-
raw
字符串对象保存的是一个字符串值,字符串的长度大于32字节,使用SDS来保存这个字符串。
embstr和raw的区别:
raw在分配和回收内存的时候只需要进行一次,而embstr则需要两次。
embstr编码的字符串是只读的不能进行修改,而raw和int是可以修改的。
列表对象(list)
-
ziplist
每个压缩列表节点保存了一个列表元素。
字符串元素长度<64字节;元素个数<512个;
例如:
rpush numbers 1 “three” 5
-
linkedlist
双端链表的每个节点都保存了一个字符串对象。
哈希对象(hash)
-
ziplist
当有新的k-v加入到哈希对象时,程序会先将保存了键的压缩列表节点推入到压缩列表表尾,然后再将保存了值得压缩列表节点推入到压缩列表表尾。(key在前,value在后)
哈希对象的键值对字符串长度<64;
键值对的数量<512
-
hashtable
字典的每一个键都是一个字符串对象,对象中保存了键值对的键。
字典的每一个值都是一个字符串对象,对象中保存了键值对的值。
集合对象(set)
-
inset
集合对象保存的所有元素都是整数值;
集合对象保存的元素数量<=512;
-
hashtable
字典的键是集合元素,字典的值是null。
有序集合对象(zset)
-
ziplist
每个集合元素使用两个紧挨在一起的压缩列表节点来保存。第一个节点保存member,第二个节点保存score。按照score从小到大的顺序排列。
有序集合保存的元素数量<128;
有序集合保存的所有元素member的长度<64;
-
skiplist
跳跃表按照分值大小从小到大保存所有集合元素,每个跳跃表节点都保存了一个集合元素:object:member,score:score。通过跳跃表便于对有序集合的范围操作,例如zrank,zrange。
字典为有序集合创建了一个从member->score的分值映射。字典中的每个k-v都保存了一个集合元素。可以O(1)查找到给定成员的score,例如zscore。
有序集合的每个元素的member是字符串对象,而score是double类型的浮点数。跳跃表和字典是通过指针来共享相同元素的member和score。不会产生重复的member和score而浪费内存。