Redis SDS

Redis里字符串字面量用c字符串,会变的就用SDS了。举例来说,set k v的时候,k用的是c字符串,而v是一个SDS。Redis的缓冲区用的也是SDS

SDS的实现

// redis设计与实现里的
struct sdshdr {
int len;
int free;
char buf[];
};
//source code
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

看起来和redis设计与实现里的介绍不一致,redis好像定义了5、8、16、32、64不同长度的sdshdr,不过长的都是一样的,看起来只是长度有区别。

SDS和C字符串的区别

常数获取长度

c字符串要遍历,O(n)

杜绝移除

c字符串用\0代表结尾,做strcat等字符串操作要自己控制溢出问题。SDS有长度

内存分配

接上节,改变字符串的操作在c里每次都要手动控制内存分配,增加或者free,很慢。SDS记录了未使用长度,实现了空间预分配和惰性空间释放两种策略。

空间预分配

就是扩容,如果修改操作后的新长度小于1MB,SDS得到两倍空间,len和free相同,再加一字节存\0
如果大于1MB,就分配1MB的未使用空间。

惰性空间释放

看起来好像是手动释放的。应该是redis会在内存分配不够的时候释放一下吧我猜。

二进制安全

就是说可以不用担心\0出现在字符串内部了,因为SDS是根据长度判断结束没有的。这样就可以用来保存图片、音频、视频、压缩文件等二进制数据。

兼容c函数

因为保留了结尾\0的结构,所以一些c字符串函数可以直接拿来用。

总结

Redis SDS_第1张图片
image.png

你可能感兴趣的:(Redis SDS)