Redis 的字符串叫着「SDS」,也就是Simple Dynamic String。它的结构是一个带长度信息的字节数组。
struct SDS<T> {
T capacity; // 数组容量
T len; // 数组长度
byte flags; // 特殊标识位,不理睬它
byte[] content; // 数组内容
}
这个和Java的ArrayList 差不多,capacity是分配数组的长度,len表示数组长度,content是表示内容。默认capacity和len长度是相同的。 如果要用append操作字符串, 按需调整空间,如果 capacity 不够容纳追加的内容,就会重新分配字节数组并复制原字符串的内容到新数组中。
embstr vs raw
Redis 的字符串有两种存储方式,在长度特别短时,使用 emb 形式存储 (embeded),当长度超过 44 时,使用 raw 形式存储。如下图:
*** embstr和Row区别
这是为啥呢?了解一下Redis的结构体
struct RedisObject {
int4 type; // 4bits
int4 encoding; // 4bits
int24 lru; // 24bits
int32 refcount; // 4bytes
void *ptr; // 8bytes,64-bit system
} robj;
一个Redis对象头需要最少16字节的存储空间。当字符串比较小的时候,SDS对象头的大小capacity+3,至少是3,意味一个字符串最小空间是19字节。而分配内存的时候,内存分配的单位是 2、4、8、16、32、64 等等。
当内存分配器分配了 64 空间时,那这个字符串的长度最大可以是44(64-19)。