简单动态字符串

  • 简单动态字符串,simple dynamic string,SDS,抽象类型,用作redis的默认字符串表示

  • 在redis中,包含字符串值得键值对在底层都是由SDS实现的

  • SDS定义

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct sdshdr {

    // 记录buf数组中已使用字节的数量
    // 等于SDS所保存字符串的长度
    int len;

    // 记录buf数组中未使用字节的数量
    int free;

    // 字节数组,用于保存字符串
    char buf[];
    }
  • 通过使用SDS而不是C字符串,Redis将获取字符串长度所需的复杂度从O(N)降低到了O(1),确保了获取字符串长度的工作不会称为Redis的性能瓶颈

  • 与C字符串不同,SDS的空间分配策略完全杜绝了发生缓冲区溢出的可能性;当SDS API需要对SDS进行修改时,API会先检查SDS的空间是否满足修改所需的要求,如果不满足的话,API自动将SDS的空间扩展至执行修改所需的大小,然后才执行实际的修改操作

  • 通过未使用空间,SDS实现了空间预分配和惰性空间释放两种优化策略:

    • 空间预分配
      • SDS将连续增长N次字符串所需的内存重分配次数从比定N次降低为最多N次
    • 惰性释放
      • SDS避免了缩短字符串时所需的内存重分配操作,并为将来可能有的增长操作提供了优化
  • 通过使用二进制安全的SDS,而不是C字符串,使得Redis不仅可以保存文本数据,还可以保存任意格式的二进制数据

  • 相比C字符串,SDS具有以下优点:

    • 常数复杂度获取字符串长度
    • 杜绝缓冲区溢出
    • 减少修改字符串长度所需的内存重分配次数
    • 二进制安全
    • 兼容部分C字符串函数