SDS 全称为 simple dynamic string,简单动态字符串
1. SDS 的用处
SDS 在 Redis 中大致有四种用处
- Redis 的 key-value 键值对中的键
- Redis 的 key-vlaue 中的 value 类型为 String 的 value
- AOF 缓冲区
- 客户端状态中的输入缓冲区
2. SDS 的 c 语言定义
每个 sds.h/sdshdr 结构表示一个 SDS 值
struct sdshdr{
//记录 buf 中已使用字节的长度
//等于 SDS 所保存的字符串的长度
int len;
// 记录 buf 中未使用的字节数量
int free;
//字节数组,用于保存字符串
//在字符串的最后保存了 '\0', 用于和 c 语言保持一致,这个字节不计算入 len 中
char buf[];
}
3.SDS 和 c 语言字符串的区别
获取字符串长度
- c 语言需要遍历字符串才能获取字符串长度
- sds 只需要访问 len 属性就可以获取字符串长度
缓冲区溢出:
- c 语言在做字符串拼接操作时可能会导致缓冲区溢出
- sds 在做拼接操作时,如果空间不够用,会体验扩充空间
对内存重分配的次数:
- c 语言只要存在更改字符串的长度行为,就需要进行内存重分配
- sds 通过未使用空间(free 属性)解除了字符串长度和底层数组长度之间的关联
- sds 的空间预分配:当修改完的字符串长度小于 1M,程序就会为 free 属性分配 len大小的空间。如果修改完的字符串大于 1M,程序就会为 free 属性分配 1M 大小的空间
- sds 的惰性空间释放:当字符串的长度缩短时,多出来的空间放在 free 中保存,等到需要的时候再释放部分 free 空间。
二进制安全:
- c 语言在遇到空字符的时候会以为字符串已经结束。(不能储存像图片,视频类似的数据)
- sds 语言都会以二进制的方式处理数据(输入保存的字符串时什么样的,输出的就是什么样的)
4. 兼容部分 c 语言函数
由于 sds 的 buf 区域最后一个字符也是存储的 ‘\0’, 和 c 语言一样,所以 sds 可以使用部分 c 语言函数。
参考资料
[1].《Redis 设计与实现》