Redis 为什么要自定义 SDS?

SDS 是 Simple Dynamic String 的缩写,意为简单动态字符串。大家都知道,Redis 提供的数据结构,均以 KV 键值来存储的,其中 Key 是字符串类型,另外,Value 值也支持字符串结构,并且在日常开发中,使用频率也是非常高的。

面试官其实想问的是,Redis 使用 C 语言开发的,那为什么它不使用 C 语言原生的字符串,而是大费周折的,要自己造轮子呢?

简单来说,C 语言的原生字符串实现过于简单(以空字符 \0 结尾的字符数组),无法满足 Redis 对性能、安全性和功能的严苛要求。

C 语言原生字符串的缺陷

C 语言原生字符串的缺陷C 语言原生字符串的缺陷

  1. 获取长度的时间复杂度为 O(N):字符串必须遍历整个字符串直到遇到 \0,才能计算出长度。这对于频繁需要长度的数据库操作是灾难性的。
  2. 缓冲区溢出风险strcatstrcpy 等函数不检查目标缓冲区大小,极易造成缓冲区溢出,是严重的安全隐患。
  3. 内存重分配频繁:每次增长或缩短字符串,都需要通过 realloc 重新分配内存,这是一个相对昂贵的系统调用。
  4. 二进制不安全:字符串中不能包含空字符 \0,因为它被用作结束标志。这使得 C 字符串无法用于存储图片、压缩数据等任意二进制数据。
  5. 修改效率低下:由于上述原因,任何涉及长度变化的修改都非常低效且危险。

基于以上原因,所以 Redis 并没有使用 C 语言原生的字符串,而是自定义了 SDS, 实现了高性能、高可靠性和功能完备等特性。