redis中对象都使用redisObjec结构,字符串对象ptr指向sdshdr结构
1 /* 2 * 保存字符串对象的结构 3 */ 4 struct sdshdr { 5 6 // buf 中已占用空间的长度 7 int len; 8 9 // buf 中剩余可用空间的长度 10 int free; 11 12 // 数据空间 13 char buf[]; 14 };
字符串对象的编码可以是int、raw或者embstr。
如果一个字符串对象保存的是整数值,那么字符串对象会将整数值保存在字符串对象结构的ptr属性里面,
并且将字符串对象的编码设置为int
这时对象结构如下
如果字符串对象保存的是一个字符串值,并且这个字符串的长度大于39(redis 4.0.1 是44)字节,那么
字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串值,并将对象的编码设置为raw。
如果字符串对象保存的是一个字符串值,并且小于等于32字节,那么字符串对象将使用embstr编码的
方式来保存这个字符串值
embstr编码是专门用于保存短字符串的一种优化编码方式,这种编码和raw编码一样,都使用redis-
Object结构和sdshdr结构来表示字符串对象,但raw编码会调用两次内存分配函数来分别创建redisObject
结构和sdshdr结构,而embstr编码则通过调用一次内存分配函数来分配一块连续的空间,空间中依次包含
redisObject和sdshdr两个结构
embstr编码的字符串对象的所有数据都保存在一块连续的内存里面,所以这种编码的字符串对象比起
raw编码的字符串对象能够更好的利用缓存带来的优势
另外,浮点数据也可以通过字符串对象保存,编码是embstr或者raw
embstr字符串是只读的,如果修改(例如append命令)编码会变成raw
创建字符串对象入口
1 /* Create a string object with EMBSTR encoding if it is smaller than 2 * REIDS_ENCODING_EMBSTR_SIZE_LIMIT, otherwise the RAW encoding is 3 * used. 4 * 5 * The current limit of 39 is chosen so that the biggest string object 6 * we allocate as EMBSTR will still fit into the 64 byte arena of jemalloc. */ 7 #define REDIS_ENCODING_EMBSTR_SIZE_LIMIT 39 8 robj *createStringObject(char *ptr, size_t len) { 9 if (len <= REDIS_ENCODING_EMBSTR_SIZE_LIMIT) 10 return createEmbeddedStringObject(ptr,len); 11 else 12 return createRawStringObject(ptr,len); 13 }
embstr编码String
1 /* Create a string object with encoding REDIS_ENCODING_EMBSTR, that is 2 * an object where the sds string is actually an unmodifiable string 3 * allocated in the same chunk as the object itself. */ 4 // 创建一个 REDIS_ENCODING_EMBSTR 编码的字符对象 5 // 这个字符串对象中的 sds 会和字符串对象的 redisObject 结构一起分配 6 // 因此这个字符也是不可修改的 7 robj *createEmbeddedStringObject(char *ptr, size_t len) { 8 robj *o = zmalloc(sizeof(robj)+sizeof(struct sdshdr)+len+1); 9 struct sdshdr *sh = (void*)(o+1); 10 11 o->type = REDIS_STRING; 12 o->encoding = REDIS_ENCODING_EMBSTR; 13 o->ptr = sh+1; 14 o->refcount = 1; 15 o->lru = LRU_CLOCK(); 16 17 sh->len = len; 18 sh->free = 0; 19 if (ptr) { 20 memcpy(sh->buf,ptr,len); 21 sh->buf[len] = '