跳至主要內容

Redis 字符串

blacklad大约 2 分钟RedisRedisRedis 设计与实现

Redis 字符串

1 SDS

Redis 内部定义了 SDS 结构体描述字符串。

struct sdshdr {
    // buf数组中未使用的字节数量
    int free;
    
    // buf数组中已经使用的字节数量
    int len;
    
    // 字节数组用于保存字符串
    char buf[];
}

1.1 SDS 的特性

  1. 常数复杂度获取字符串的长度,对于 C 的字符串只能通过遍历整个字符串得到字符串长度,而 SDS 对象可以直接通过 len 属性获取字符串的长度。
  2. 防止缓冲区溢出,在执行字符串拼接函数时,可能会由于空间分配导致内存溢出。而 SDS 提供的 api 内部会进行检测,避免这个问题。
  3. 对于 C 字符串的修改,每次修改都需要重新分配内存。Redis 通过空间预分配和惰性空间释放进行优化。

1.2 空间预分配

通过空间换时间,当 SDS 需要增长字符串时,会额外分配一半的空闲空间(最大为1Mb)。避免每次都需要空间分配。

1.3 惰性空间释放

当字符串长度需要缩短时, 不会立即回收空闲的字节,而是先通过free记录下来,提供后续使用。也可以通过api释放空间。

  1. C 语言只能保存特定的字符串,且除了字符串末尾,其他地方不能包含空白字符,负责会被c语言认为是字符串结尾。而 SDS 通过 buf 字节数组保存数据,len记录字符串的结尾。
  2. 兼容 C 的字符串,对于 buf 数组,最后一个字节用 '\0' 表示,保留了 C 字符串的结构,便于使用c的一些函数,且该字符不计算在 len 中。
上次编辑于:
贡献者: blacklad