简单动态字符串
Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串),而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型, 并将 SDS 用作 Redis 的默认字符串表示。内部结构实现上类似于 Java 的 ArrayList。
SDS 的结构是一个带长度信息的字节数组:
struct SDS<T> {
int free; // buf 剩余可用长度
int len; // buf 已占用长度
char buf[]; // 实际保存字符串数据的地方
}
ℹ️
对 buf 分配一些额外的空间,并使用 free 记录未使用空间的大小。Redis 字符串是可以修改的,它支持
append
操作。如果数组没有冗余空间,那么追加操作必然涉及到分配新数组,然后将旧内容复制过来,再 append
新内容。如果字符串的长度非常长,这样的内存分配和复制开销就会非常大。这是利用空间换时间的策略。使用 SDS 的原因:
- 二进制安全。C 字符串是以
\0
字符为结尾的,如果客户端传过来的字符串包含\0
字符,那么服务器在处理这个字符串时,会将\0
后的字符串舍弃掉。适配不同语言的客户端。 - 兼容部分 C 字符串函数。SDS 结构体中的
content
中的字符串是以字节\0
结尾的字符串,之所以多出这样一个字节,是为了便于直接使用glibc
的字符串处理函数。
扩容策略
字符串在长度小于 1M 之前,扩容空间采用加倍策略,也就是保留 100% 的冗余空间。当长度超过 1M 之后,为了避免加倍后的冗余空间过大而导致浪费,每次扩容只会多分配 1M 大小的冗余空间。
Redis 的 key
Redis 是一个键值对数据库,key 是字符串,value 是字符串、列表、哈希、集合、有序集合。
虽然 Redis 可以使用非字符串类型作为 key,例如:
redis> set 100 100
OK
redis> get 100
"100"
redis> set 0.1 200
OK
redis> get 0.1
"200"
虽然看起来是数字或者浮点数,但是 Redis 会将其作为字符串来处理。
最后更新于