从 C 字符串到 SDS 的性能优化之路
2010 年,Redis 首次引入 SDS 作为字符串实现。 此前直接使用 C 字符串(char*),存在缓冲区溢出和 O(n) 长度获取问题。
引入高效的字符串追加(APPEND)操作。通过记录已用长度 len, 避免每次追加都重新分配内存。
优化内存预分配算法。当字符串小于 1MB 时,倍增预分配; 大于 1MB 时,每次多分配 1MB。显著减少内存碎片。
3.2 是转折点!引入 5 种 SDS 类型,头部从 8 字节压缩到 1-3 字节。 短字符串使用 embstr 编码,string 和 redisObject 连续内存分配。
引入 Redis Modules API,允许自定义数据类型。 string 类型保持稳定,进一步优化内存分配策略。
Redis 7.0 引入 Redis Functions(取代 Lua 脚本), string 类型支持更高效的 int 编码优化(当值为纯数字时)。
embstr = embedded string,将 redisObject 和 sds 分配在同一块连续内存
两次内存分配 ❌
一次内存分配 ✅
Redis String 从最初的简单封装,到今天的高性能动态字符串,
经历了多次精妙的优化:
空间换时间(预分配)→
类型分桶(SDS_TYPE_X)→
内存对齐(embstr)
每一个版本都在追求更低的内存开销和更高的访问效率。
这也是 Redis 能够成为内存数据库标杆的核心秘密之一。