String 底层 SDS 原理
候选人小李在美团的一面中,面试官问道:
"Redis 的 String 底层用的什么字符串?为什么不用 C 的 char 数组?"
小李说:"SDS 吧,比 C 字符串好。"面试官追问:"好在哪里?"
小李说:"...快?"面试官:"SDS 的 header 里存了什么?为什么要有 len 字段?"
小李愣住了,说:"存长度...方便取?"
面试官继续:"那 SDS 的空间预分配机制是什么?惰性删除又是什么?"
小李彻底卡住。
【面试官心理】 这道题我用来考察候选人对 Redis 底层实现的理解程度。知道 SDS 比 C 字符串好的人很多,但能说出"好在哪里"——O(1) 长度获取、二进制安全、空间预分配——的人不到 30%。能讲清楚 SDS header 结构和预分配算法的,基本都看过 Redis 源码。
一、SDS 是什么 🔴
1.1 C 字符串的三大缺陷
在聊 SDS 之前,先说说 C 字符串为什么不够用。
问题一:长度获取是 O(n)
C 字符串用 \0 结尾,获取长度需要遍历整个字符串。对于 Redis 这种高频 get/set 的场景,每次都要从头到尾扫描一遍,性能根本无法接受。
问题二:缓冲区溢出
问题三:二进制不安全
C 字符串遇到 \0 就截断,无法存储图片、音频等二进制数据。
1.2 SDS 结构
SDS(Simple Dynamic String)的核心改进就是在字符串前面加了一个 header:
关键设计:len 字段直接存储长度,strlen 是 O(1)。
1.3 ❌ 错误示范
候选人原话:"SDS 就是加了个长度,没别的了。"
问题诊断:
- 只看到了表面,不知道空间预分配
- 不理解惰性删除的设计意图
- 不了解二进制安全的具体含义
面试官内心 OS:"这个候选人肯定只是简单翻过 Redis 源码,没有理解 SDS 设计背后的工程权衡。"
1.3 标准回答
SDS 的四大优势:
【面试官心理】 SDS 是 Redis 最基础的数据结构,但也是最能体现设计功力的地方。我追问空间预分配和惰性删除,是想看他有没有从"系统设计"的角度思考 Redis。知道 SDS 有这些优化的占 40%,能说出具体实现细节的占 15%。
二、空间预分配 🔴
2.1 为什么需要预分配?
如果 SDS 每次 append 都要重新分配内存,性能会非常差:
Redis 的空间预分配策略:
2.2 追问
面试官追问:为什么 >= 1MB 后不再翻倍,只加 1MB?
这是 P7 级别的追问。翻倍策略在数据量大时会导致严重的内存浪费:
- 1MB 翻倍 = 2MB,浪费 50%
- 100MB 翻倍 = 200MB,浪费 100MB
改为"加 1MB"后:
- 100MB + 1MB = 101MB,浪费率降到 1%
这是一个典型的时间换空间 vs 空间换时间的权衡。Redis 选择了在数据量大时用更保守的预分配来节省内存。
【面试官心理】 这道追问我想验证的是候选人有没有"系统级的资源意识"。能说出翻倍策略的占 30%,能解释 1MB 阈值的占 10%。Redis 的设计处处体现了"小数据省内存、大数据省空间"的理念。
三、惰性删除 🟡
3.1 什么是惰性删除?
SDS 的删除操作不会立即释放内存,而是记录新的长度:
3.2 惰性删除 vs 立即释放
3.3 真正的内存回收
SDS 提供了手动释放接口:
【面试官心理】 惰性删除是 Redis 中一个非常巧妙的优化,但大多数候选人从未注意到。这个问题我通常用来试探候选人是不是真的看过 Redis 源码,而不是道听途说。
四、二进制安全 🟡
4.1 为什么 C 字符串不是二进制安全的?
4.2 SDS 的二进制安全
SDS 按 len 字段判断结束,不依赖 \0:
4.3 应用场景
【面试官心理】 二进制安全这个问题,我想验证的是候选人有没有实际使用场景。很多候选人能背出"SDS 是二进制安全的",但说不出实际应用——比如为什么 Redis 可以用 String 存储图片和序列化对象。
五、综合对比
六、生产避坑
:::warning ⚠️ SDS 的两大生产隐患:
-
大 Key 字符串:预分配导致 String 内存可能比实际数据大很多。100MB 的 String 实际占用可能超过 200MB(翻倍预分配)。
-
大量短字符串:Redis 内部大量使用 SDS(如 key 名、命令参数),jemalloc 的内存碎片率可能高达 1.5x 以上。 :::
排查方法:
:::tip 💡 生产优化建议:
- 字符串 value 超过 10KB 时,考虑拆分或使用其他存储
- 关注
mem_fragmentation_ratio,过高时重启或使用 MEMORY PURGE - Redis 7.0 引入的动态 AOF 碎片管理可以缓解这个问题 :::
【面试官心理】 这道题我想最终验证的是候选人的"系统思维"。SDS 看似简单,但背后涉及内存管理、性能优化、系统设计等多个维度。能把 SDS 的设计讲清楚并联系到生产优化的,基本都是 P6 以上。