1.Redis 中以 key-value 的形式存储, key 固定是字符串, 使用字符串对象进行表示, value 可以是字符串 (String), 列表 (List), 哈希 (Hash), 集合 (Set), 有序集合 (ZSet).
2. 在内存中, 每个 Key-Value 都被划分成 DictEntry,RedisObject 以及具体对象, DictEntry 又分别包含指向 Key 和 Value 的指针, 以及指向下一个 DicEntry 的指针, 指向 key 和 value 的指针也是以 RedisObject 的形式
3.Redis 使用了自定义的字符串类型, 不同于 C 语言的字符串, Redis 使用 sdshdr 结构来表示字符串对象 (SDS)
- struct sdshdr {
- int len;
- int free;
- char buf[];
- }
len 属性: 字符串的长度
free 属性: 未使用的字节数量
buf 数组: 字符串的底层实现用于存储字符
buf 数组中会有 \ 0 空字符, 该空字符不会记录在 len 属性中
C 语言中存储的字符串的字节数组长度是其总长度的 N+1, 因为最后一个是结束符, 所以如果要对字符串进行追加, 需要重新分配内存, Redis 的 SDS 通过未使用空间解除了字符串长度和底层数组长度之间的关系, 在 SDS 中 buf 的长度不一定就是字符串长度 + 1, 数组里面还可以包含未使用的字节, 通过这种未只用的空间, SDS 就实现了空间预分配和惰性空间释放两种策略, 减少由于字符串修改导致的内存重新分配的次数.
空间预分配是用于优化 SDS 保存的字符串的增长操作, 当需要对 SDS 保存的字符串进行增长操作时候, 程序除了会分配必须的空间外, 还会为 SDS 分配额外的未使用空间
惰性空间释放用于优化 SDS 保存的字符串缩短操作, 当需要对 SDS 保存对字符串进行缩短操作时候, 程序不会立即使用内存重分配来回收缩短后多出来的字节, 而是使用 free 属性将这些多出来的字节数量记录下来, 等待将来使用.
来源: http://www.bubuko.com/infodetail-3394767.html