redis的简单动态字符串

概念

redis在c的基础上编写,但是redis的许多数据结构是不同于c的数据结构。
redis的字符串表示是利用自己构建的SDS(简单动态字符串)作为默认字符串表示的。
而c默认的字符串表示,被redis用来作为字面量的表示方法,字面量,就是字符串是固定的,不会改变的。

SDS的用处:

  • 保存动态字符串值
  • 缓冲区:AOF缓冲区、客户端状态的输入缓冲区

sds定义:

struct sdshdr {
	int len; // 已使用的buf[]长度
	int free; // 未使用的buf[]长度
	char buf[]; // 保存char字节, buf[]数组默认结尾为‘\0’,且不被记入len。
}

SDS与c字符串的区别有:

  • 获取字符串长度复杂度:
    • c需要遍历字节数组以获得字符串长度,sds只需要获取len值即可。
  • 杜绝缓冲区溢出:

    如上图所示:在内存中,紧挨着两个c字符串,当执行strcat(s1,'Cluster')时,默认s1的长度足够,那么‘Cluster’就会覆盖后面s2的内容,即“内存溢出”
    Sds的api进行修改时,会首先检查sds的内存空间是否足够,如果不够会触发自动扩容

sds空间策略:

空间预分配

概念:当sds的api对sds进行扩容操作时,不仅会分配所需的空间,还会为sds分配多余的空间
内容:

  • 如果sds被修改后,len的长度小于1MB,那就会为sds多分配len长度的空间,此时len=free
    举例说明:修改'hello'为'hello,redis', 修改后长度为11字节,那么就会在修改后,继续为sds分配11字节的空间,此时len = free。sds实际长度为11+11+1=23字节。
  • 如果sds被修改后,长度大于1MB,那么就会在修改后,继续为sds分配1MB的free空间。

惰性空间释放

概念:sds删除部分字符串后,不会讲空出来的空间立即删除。
内容:

  • 如图,部分空间即使存储的内容被删除也不会被立即释放,会作为free空间保留在sds中,在之后的增长操作中使用。为避免空间浪费,有api真正释放free空间。

sds二进制安全

二进制安全

概念:sds不是以'\0'作为字符串结尾,所以不用担心某些以'\0'分隔的数据格式。
内容:

  • ‘Redis Cluster’, 如果使用二进制保存,c的字符串函数只会识别Redis,而忽略后面的'Cluster', 这就导致c的字符串只能用来保存文本,而图片、视频等二进制数据无法保存。而sds的二进制安全,表示sds的buf[]能直接处理二进制数据,这也是buf[]是字节数组的原因。因为sds使用len属性而不是空字符串判断结尾。

兼容C部分函数

因为SDS字符串以'\0'结尾,所以可以兼容c的部分字符串函数。

posted @   新游  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
点击右上角即可分享
微信分享提示