Redis中级篇

🍎Redis底层结构

Redis 摒弃了C字符串,转而采用自己实现的的名为简单动态字符串的抽象类型 简称SDS

传统C字符串是以\0结尾的 若不以这个结尾表示字符数组 C语言中没有String类型,而是通过char[]来表示

🍉SDS的定义

struct sdshdr{
    //记录buf数组中已使用字节的数量
    //即SDS所保存字符串的长度
    int len;
    //记录buf数组中未使用字节的数量
    int free;
    //字节数组用于保存字符串
    char buf[];
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HNJllfXH-1669856849783)(Redis中级篇.assets/image-20221116103214190.png)]

SDS遵循了以空字符结尾的惯例,保存空字符的1字节空间不计算在SDS的len属性里,好处就是SDS可以重用C字符串函数库里的函数

空字符分配额外的1字节空间,以及添加空字符到字符串末尾等操作由 SDS函数自动完成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lnlkj0yL-1669856849784)(Redis中级篇.assets/image-20221116103131202.png)]

🍉SDS与C的区别

🍓获取字符串长度复杂度

C字符串并不记录字符长度 这就导致在获取字符长度时需要遍历来统计字符长度 复杂度为O(n)

而SDS本身就有len属性,获取字符长度的复杂度为O(1)

🍓缓冲区溢出

C字符串不记录自身长度,当我们在做字符串拼接时没有给足够的内存来存储拼接的字符串,就会造成缓冲区溢出

SDS会检查是否空间是否满足,如果不满足会自动进行扩容

🍓内存分配次数

C字符串的底层实现总是用N+1个字符长度的数组来存储N个字符,每次增加或者删减字符都需要做一次内存重新分配

增加不重新分配会造成内存溢出 删减不重新分配会造成内存泄漏

在SDS中 数组长度 不一定是字符数量加一,数组里面可以包含未使用的字节,而未使用的通过free属性来记录

通过未使用空间,SDS实现了空间预分配惰性空间释放两种优化策略

🥭空间预分配

空间预分配用于优化SDS的字符串增长操作

当对SDS修改后长度小于1MB,程序会分配和len属性同样大小的未使用空间,也就是len和free是相同的

如修改后 SDS的len将变成13字节 那么该buf的实际长度将是 13+13+1=27 字节

当SDS修改后长度大于1MB,那么程序会分配1MB的未使用空间

如:修改后SDS的len是30MB, buf的实际长度是 30MB+1MB+1byte

🥭惰性空间释放

惰性空间释放用于优化SDS的字符串删减操作

当需要缩短字符串长度时,程序并不会立即使用内存重分配来回收多出来的字节,而是使用free属性将这些字节的数量记录起来,并等待将来使用

🍓安全性

C字符串中不允许中间有空格,否则会被误认为是字符串结尾,使得C字符串只能保存文本数据,而不能保存 图片 音频视频之类的二进制数据

🍓兼容C字符串函数

SDS遵循C字符串的以空字符结尾的惯例,就可以直接使用C的一些函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值