Redis 字符串
大约 2 分钟RedisRedisRedis 设计与实现
Redis 字符串
1 SDS
Redis 内部定义了 SDS 结构体描述字符串。
struct sdshdr {
// buf数组中未使用的字节数量
int free;
// buf数组中已经使用的字节数量
int len;
// 字节数组用于保存字符串
char buf[];
}

1.1 SDS 的特性
- 常数复杂度获取字符串的长度,对于 C 的字符串只能通过遍历整个字符串得到字符串长度,而 SDS 对象可以直接通过
len
属性获取字符串的长度。 - 防止缓冲区溢出,在执行字符串拼接函数时,可能会由于空间分配导致内存溢出。而 SDS 提供的
api
内部会进行检测,避免这个问题。 - 对于 C 字符串的修改,每次修改都需要重新分配内存。Redis 通过空间预分配和惰性空间释放进行优化。
1.2 空间预分配
通过空间换时间,当 SDS 需要增长字符串时,会额外分配一半的空闲空间(最大为1Mb)。避免每次都需要空间分配。
1.3 惰性空间释放
当字符串长度需要缩短时, 不会立即回收空闲的字节,而是先通过free记录下来,提供后续使用。也可以通过api释放空间。
- C 语言只能保存特定的字符串,且除了字符串末尾,其他地方不能包含空白字符,负责会被c语言认为是字符串结尾。而 SDS 通过
buf
字节数组保存数据,len
记录字符串的结尾。 - 兼容 C 的字符串,对于
buf
数组,最后一个字节用'\0'
表示,保留了 C 字符串的结构,便于使用c的一些函数,且该字符不计算在len
中。