redis对象
redis对象有redisObject组成,
type struct redisObject{
//类型
unsigned type:4;
//编码
unsigned encoding:4;
void *ptr;
}
其中type记录了对象的类型,有5种对应的是字符串对象,列表对象,
哈希对象,集合对象和有序集合对象。encoding属性记录了对象的编码,下图是编码对应的实现
字符串对象
字符串的编码组成可以是int,raw或者embstr
整数值可以用long型存储就用long型来表示,ptr类型设置为long,如果是字符串类型小于32字节用embStr,如果是大于32位字节使用简单动态字符串sds并将编码设置为raw
embstr和简单动态字符串的对比,embstr同样需要redisObject和sdshdr,但是embstr编码通过一次内存分配函数来分配一块连续的空间,空间中依次包含redisObject和sdshdr
- embstr将创建字符串所需要的内存分匹配次数从两次降为一次,释放同样降为了一次
- embstr两个对象在连续的空间能够更好的利用缓存。
编码转换
int类型append了字符串会变成raw类型,embstr添加了字符串会变成raw类型embstr空间同时分配,它是只读,一旦被修改,转换成raw
字符串命令的实现
列表对象
可以是ziplist和linkedList,如果使用的是压缩列表节点每一个entry保存一个列表元素,rpush numbers 1 “three” 5
- 压缩列表结构
zlbytes表示压缩列表总长
zltail表示压缩列表起始地址加上zltail就是表尾节点的起始地址
zllen表示列表有几个节点
节点构成
previous_entry_length是前一个节点程度,通过这个长度和节点起始地址可以得到前面一个节点的起始地址向前遍历
- linkedlist结构
编码转换
- 列表对象保存的所有字符串元素的长度都小于64字节
- 列表对象保存的元素数量小于512个
不能满足这两个条件的列表对象需要使用linkedlist编码
哈希对象
哈希对象的编码可以是ziplist或者hashtable
ziplist实现hash对象试讲key和value放在一起,key在前,value在后。先添加的hash对象在表头后添加的在表尾。
编码转换
哈希对象保存的字符串长度都小于64字节
哈希对象保存的键值对数量小于512个,不满足这两个条件需要使用hashtable编码
集合对象
集合对象的编码可以是intset或者hashtable
hashtable实现集合每一个键都是字符串对象,每一个字符串对象包含一个集合元素,value设置为空
编码转换
集合对象保存的所有值都是整数值
集合对象保存的元素数量不超过512个
不满足以上两个条件使用hashtable
有序集合对象
有序集合对象可以是ziplist和skiplist
有序集合对象使用压缩列表作为每个集合元素使用两个紧挨在一起的压缩节点来保存,第一个保存节点的成员,第二个保存节点的分值score
压缩列表按分值从小到大排序,小的在表头,大的在表尾
编码的转换
ziplist在下列条件时使用
- 有序集合保存的元素数量小于128个
- 有序集合保存的所有元素成员的长度都小于64字节