Redis数据结构解析(一) -- SDS

175 阅读1分钟

简单动态字符串

基本结构

simple dynamic string(sds)将c语言的字符串进行了简单的封装。

image.png

  • free 记录了目前未使用字节的数量(此处为1)
  • len 记录了buf数组当前已使用字节的数量(此处为3)
  • buf 用于保存字符串(此处为"RGB")

使用go语言的代码实现

type sdshdr struct {
   len int

   free int

   buf[] byte
}

优点

这样设计相比于c语言的字符串有很多优势

  1. 获取长度不用遍历
  2. 防止溢出
  3. 减少重分配次数
  4. 二进制安全
  5. 兼容部分c字符串的函数

重分配

因为c语言的字符串是无法修改的,而Redis这样的结构设计后可以动态扩容。扩容就会涉及到重新分配新的空间。一般我们能想到的策略就是分配旧的长度加新的长度的新字节数组,然后复制过去。

但是Redis被要求速度快,数据频繁修改且较大的话会极度影响性能和效率。

于是sds实现了空间预分配惰性空间释放两种优化策略

  • 空间预分配:

    1. len < 1MB --> free = len
    2. len >= 1MB --> free = 1MB 预分配也就是给free设置大一点
  • 惰性空间释放:

    不直接释放空间,而是用增加free的值来方便后面再扩展

二进制安全

c语言字符串只能保存文本,不能保存二进制,例如: '\0'不能出现在中间,c语言会误认为已经结尾了

所以sds底层用的是字节数组确保二进制的安全,主要是Redis的sds使用len来判断字符是否结束