Redis数据结构探索之动态字符串SDS(simple dynamic string)

最近看了Redis的SDS动态字符串的一些知识,总结一下。本篇只写SDS的一些数据结构相关的,不涉及其他内容。

大家都知道Redis底层是用C写的,但是Redis并没有直接使用C的字符串来进行保存(以空字符结尾的字符数组),而是自己构建了一种简单的动态字符串SDS,默认为Redis的字符串表示。

本篇文章用来说明SDS和C字符串不同之处,为什么使用SDS而不是直接使用C字符串。

简单演示字符串的键值都是由SDS实现

在这里插入图片描述
如果客户端执行以上命令

  • 键值对的键是一个字符串对象,底层实现是一个保存着字符串"msg"的SDS。
  • 键值对的值时一个字符串对象,底层实现是一个保存着字符串"helloworld"的SDS。

简单介绍一下SDS的结构

在这里插入图片描述
在这里插入图片描述

  • free值的值为0,表示这个SDS没有分配任何未使用空间
  • len属性的值为5,表示SDS保存了一个长度为5字节的字符串
  • buf属性是一个char类型的字符数组,最后一个则保存了空字符‘\0’
  • SDS遵循了C空字符结尾的惯例,但是该空字符不计算在len属性上,为空字符额外给1字节的空间以及添加空字符在字符结尾等操作,都是SDS函数自己调用完成的,对于用户来说是透明的。遵循C空字符结尾的惯例的好处是可以重用一些C字符串函数库的函数操作。

SDS与C字符串的区别

1.获取字符串长度的时间复杂度

C字符串并不记录自身长度的信息,所以如果要获取字符串的长度,必须从头到尾遍历一遍字符串的长度,直到遇到空字符结尾为止。这个操作的复杂度为O(N)。和C不一样的是,SDS在len属性上记录了字符本身长度,其复杂度是O(1)。设置和更新SDS的len属性都是SDS的API自动完成的,无需手动操作。Redis获取字符串长度的复杂度从O(N)降底到O(1),这确保了获取字符串长度的工作不会成为Redis的性能瓶颈。

2. 杜绝缓冲区溢出

C字符串不记录自身长度,假如执行strcat函数进行拼接字符的时候,没有为之前的字符串分配足够的空间,就会导致数据的溢出。与C不同的是,SDS的空间分配策略完全杜绝了发生缓冲区溢出的可能性,当SDS API要修改SDS时,API会先检查SDS是否满足修改所需的要求,不满足的话会自动的扩展至执行修改所需的大小,所以不会出现缓冲区溢出的问题。

3.减少修改字符串时带来的内存重分配次数

在SDS中,数组里面可以包含未使用的字节,记录在free属性中,因为如果每次修改字符串长度要执行一次内存重新分配的话,光是分配这一块时间都会很浪费,也会对性能有一定的影响。

4.二进制的安全

C字符串里面不能包含空字符,不然最先被程序读入空字符会被误认为字符串结尾,所以C字符串只能保存文本数据,而不能保存像图片、音频、视频、压缩文件等这样的二进制数据。而SDS的API是二进制安全的,所有SDS API都会以处理二进制的方式来处理SDS存放在buf数组里面的数据。这也是我们SDS的buf属性成为字节数组的原因,Redis不是用该数组来保存字符,而是用它来保存一系列的二进制数据的。

5.兼容部分C字符串的函数

比如说是<string.h>的strcasetemp函数之类的。这里就不一一列举了。。。。通过遵循C字符串以空字符结尾的惯例,SDS有需要时可以重用<string.h>函数库。从而避免了不必要的代码重复。

贴张图

在这里插入图片描述

SDS对未使用空间的两种空间策略

1. 空间预分配

  • 空间预分配用于优化SDS字符串增长操作,当SDS的API对一个SDS进行修改并空间扩展时,程序不仅会为SDS分配所需要的空间,还会给它分配额外的未使用空间。
  • 对SDS修改后的len值小于1MB,那么程序会分配给len属性一样大小的未使用空间,这时SDS的len属性和free属性的值相同。
  • 对SDS修改后的len值大于等于1MB,那么程序会分配1MB的未使用空间。
  • 通过这种空间预分配,Redis可以减少连续字符串增长操作所需要的内存重分配次数。将连续增长N次字符串所需的内存重分配必定为N次降低为最多为N次。

2.惰性空间释放

  • 用于优化SDS的字符串缩短操作,当SDS的API需要缩短SDS保存的字符串时,程序并不会立即使用内存重分配来回收缩短后多出来的字节,而是会将这些字节的数量记录到free属性中,并等待将来使用。
  • SDS也提供相应的API,当我们有需要时可以释放SDS的未使用空间,这样就不会导致这种策略会造成内存浪费。

以后有时间的话还会继续写Redis的一些数据结构。慢慢来把,一步一个脚印。加油!!

猜你喜欢

转载自blog.csdn.net/weixin_41649090/article/details/89155472
今日推荐