浅谈redis之SDS

什么是SDS

SDS:全名 simple dynamic string,意为简单动态字符串,作为redis里的一种数据结构,它有着普通C字符所不具备的一些特点.

SDS结构

struct sdshdr {
   
	int len;
	int free;
	char buf[];
}
len 意指SDS所保存字符的长度
free 则指buf数组中未使用字节的数量
buf 字节数组,用于保存字符串

从结构设计上,我们可以对 SDS的设计的优点可窥一二

len的作用

首先从len开始,为什么SDS会记录一个len值,熟悉遍历大法的我们知道,要想知道一个字符串的长度,最原始的办法是从首位数到末位,假如我们有一个长度为n的字符串,在未记录其长度时,我们要想知道其len值,需要话费的时间会是O(N),如果我们是使用的SDS记录的字符串,则花费时间使用STRLENO(1),花费的时间越少,意味着性能越高.

free的作用

free,意指buf数组还有多少空间是未使用,这个值一般用在buf空间扩展,以及添加新值时会用到。不同于C字符串的扩张,SDS API在对SDS进行修改时,会先检查SDS的空间是否满足所需需求,若不满足,API会自动将SDS的大小扩展至所需空间.这样做的好处是不会有缓冲区的溢出.

buf的作用

SDS的API都是二进制安全(binary-safe)的,通俗的来说SDS的API通过某种机制,保证了读写字符串的时候不会损害其内容,因为在C语言中,“\0”表示了字符串的结束,出现这个字符,字符串就会被截断,造成错误的字符,而在sds中即使字符串里有“\0”,也不会被截断,除非是redis自己的结尾字符,保证了读写的一致性.虽然SDS是二进制安全的,但是它还是兼容了一部分C字符的特性.

简单示例

现在我们,往SDS保存madpudding,按照上述结构,存入字符的SDS的长度是10,而buf里的前10个字节分别保存madpudding 10个字符串.实际上buf里会有11个字符,sds还是会以\0,作为字符结尾.

SDS机制

重新分配内存

分配内存机制
小于1MB情况

如果对sds进行修改后,整体的长度小于1MB,那么redis分配的是和len属性同样的大小空间,以madpudding为例,是10(buf长度)+10(free空间)+1(结尾字符).

大于1MB情况

假如修改后整体长度大于20MB,则实际空间是20MB(buf长度)+1MB(free空间)+1(结尾字符).

为什么这样分配

为什么redis会为sds这样分配空间呢?假设在实际使用中,有个sds一直在增加,按上述分配法,则在n次扩展中,sds最多重新分配n次空间,要知道io是很消耗性能的,最多n次n次,性能差距是非常大的.

惰性释放内存

假如sds的字符,一直在减少,那么sds会立马释放未使用的空间嘛?答案是否定的,sds只会在free中依次记录,等待将来使用。这样做的目的是避免了缩减字符而重新释放内存,并为将来可能有的增长提供了空间基础.当然sds提供了真正需要释放空间的命令,让开发者不用担心惰性释放造成空间浪费.

相关推荐

  1. redisSDS

    2024-02-23 14:38:02       48 阅读
  2. MySQL索引

    2024-02-23 14:38:02       343 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-23 14:38:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-23 14:38:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-23 14:38:02       82 阅读
  4. Python语言-面向对象

    2024-02-23 14:38:02       91 阅读

热门阅读

  1. Flink 侧输出流(SideOutput)

    2024-02-23 14:38:02       47 阅读
  2. int128的实现(基本完成)

    2024-02-23 14:38:02       54 阅读
  3. qt creator5.15.2用的是什么版本的图形api?

    2024-02-23 14:38:02       48 阅读
  4. 【软件设计模式之迭代器与组合模式】

    2024-02-23 14:38:02       50 阅读
  5. 【OpcUA开发笔记 2】open62541在Linux下编译及Qt开发

    2024-02-23 14:38:02       47 阅读
  6. 日常leetcode代码思路总结(持续更新)

    2024-02-23 14:38:02       57 阅读