redis的动态字符串 SDS

1、Redis的SDS

  redis中使用的默认字符串与c语言默认使用的不太一样,C语言使用空字符结尾,Redis自己封装了一种简单的动态字符串(simple dynamic string,SDS)。在源代码sds.h中可以找到SDS的定义(本文参考3.0.0版,3.2.0之后会有变化),如下所示:

1 //sds.h
2 struct sdshdr {
3     unsigned int len;
4     unsigned int free;
5     char buf[];
6 };

可以用下图来说明一下:

len值为5:表示该SDS有5个字符,

free值为0:表示该SDS没有分配任何多余的空间

buf是一个char类型的数组。前面存储len个有效字符。

  SDS也遵循字符串以'\0‘结束的习惯,最后的'\0’不计算在len内,完全由redis函数自己添加。因此,可以直接使用c的函数来处理该buf。

       free值不为0时,'\0'的位置如下图所示:

2、SDS与C字符对比的优势

  • len记录了字符的长度,因此可以以常数复杂度获取字符串长度,而普通的字符串需要经过遍历之后才能获取其长度。
  • free记录了剩余空间,可以避免缓冲区溢出。C语言的字符串是可以直接追加的,默认假设有多余空间可以使用,一旦假设不成立,则会出现溢出。
  • 通过预配内存,以及使用函数及时调整len和free,在free空间足够时,可以避免重新分配内存(申请内存是比较耗时的操作)。在减少字符串长度时也不必立即释放内存。
  • 二进制安全:C字符串遇到空字符则认为已经结束,无法表示一些中间含有空字符的二进制数据,redis使用len记录长度,而不是空字符判断是否结束。redis不仅仅是用来保存字符串用的,可能用来存储图片,视频,压缩文件等二进制数据。
posted on 2019-12-26 14:47  william-zou  阅读(430)  评论(0编辑  收藏  举报