Redis SDS的5种类型
Redis SDS的5种类型
1. 结构概览与区别
为了极致地节省内存,Redis 开发者并没有使用一种通用的结构,而是根据字符串的长度,定义了五种不同的 Header 结构。这五种类型的核心区别在于:用于保存字符串长度(len)和分配空间(alloc)的变量类型不同。
| 类型 | len变量类型 | alloc变量类型 | flags占用 | 最大容纳长度 | Header自身占用 |
|---|---|---|---|---|---|
| sdshdr5 | 无 (由 flags 位域存储) |
无 | 1字节 | 31 字节 | 1字节 |
| sdshdr8 | uint8_t (1字节) |
uint8_t(1字节) |
1字节 | 255 字节 | 3字节 |
| sdshdr16 | uint16_t (2字节) |
uint16_t(2字节) |
1字节 | 64 KB | 5字节 |
| sdshdr32 | uint32_t (4字节) |
uint32_t(4字节) |
1字节 | 4 GB | 9字节 |
| sdshdr64 | uint64_t (8字节) |
uint64_t(8字节) |
1字节 | $2^{64}-1$ 字节 | 17字节 |
⚠️:Header表示元数据信息,即为 flag + len + alloc (sdshd5没有 len 和 alloc)
2. sdshdr5:特殊的“超短”结构
1 | |
由于没有 alloc 字段,它无法记录剩余可用空间,因此不适合频繁修改的字符串。在 Redis 中,这种类型通常只用于只读的短键名。
3. sdshdr8/16/32/64:标准结构
1 | |
__attribute__ ((__packed__)):这是 C 语言的一个特性,告诉编译器取消结构体对齐。这样 Header 就会紧凑排列,不会在变量之间插入填充字节,进一步压榨内存空间。
4. 为什么要分这么多类?
Redis 作为内存数据库,内存利用率是生命线。
内存节省:如果你只需要存储一个长度为 10 的字符串,用
sdshdr8只需要 3 字节的 Header;如果强制用sdshdr64,光 Header 就要 17 字节。在拥有数亿个 Key 的环境下,这种差距会被放大到 GB 级别动态升级:当一个字符串因为追加(Append)操作而增长时,Redis 会检测当前 Header 是否还能容纳新长度。如果不够,Redis 会自动将其升级为更高阶的 SDS 类型
注意⚠️:升级是单向的。 为了减少频繁内存重分配带来的开销,Redis 官方实现中,SDS 结构通常不会在字符串变小时自动“降级”。即使你把一个巨大的字符串截断得很短,它依然会保留之前的 Header 类型和已分配的内存,直到该 Key 被删除或重写。如果未来又要拼接这个字符串,这些多出来的空间就能派上用场。
Redis SDS的5种类型
http://example.com/2026/02/05/Redis-SDS的5种类型/