redis-redis设计与实现-数据结构与对象

内容源于 《redis 设计与实现 》

一、概念
Redis 没有使用C语言传统的字符串表示 (以空字符结尾的字符数组)
而是自己构建了一种名为简单动态字符串(Simple dynamic string ,SDS)
并将SDS做为Redis的默认字符串表示
当Redis需要一个可以被修改的字符串值时,Redis就会使用SDS来表示字符串值,比如在Redis
数据库里面,包含字符串的键值对在底层都是SDS实现的

二、使用案例

1.用来保存数据库中的字符串值
redis> set msg “hellowolrd”
OK

存储情况:
Redis会在数据库中创建一个新的键值对
1.键是一个字符串对象(msg),对象的底层实现是一个保存着字符串 “msg” 的SDS
2.值也是一个字符串对象,对象底层实现是一个保存着字符串“helloworld”的SDS
2.SDS被用作缓冲区(buffer):
1.AOF模块中的AOF缓冲区
2.客户端状态中的输入缓冲区,都是由SDS实现的

三、结构
在这里插入图片描述
SDS 在结构中 使用 buf (字节数组) 保存字符串,但同样使用一些变量去记录 SDS 的一些信息
如:
1.int len 记录 buf 字节数组被使用的长度,及SDS字符串的有效长度
2.int free 记录 buf 字符数组未被使用的长度,及buf数组的空闲长度

优点:
1.通过对字节数组的包装,可以做到字符串的有效表示
2.通过使用一些变量记录相应的值,在获取SDS 有关信息的时候,效率会
非常高,无需遍历字符串数组 buf 就可以直接获取有关信息
缺点:
1.需要自己实现相应的结构
2.需要使用额外的空间存储有关信息
3.需要实时的关注并修改相关信息变量

注意:SDS的buf字符数组中保存了 空字符 ‘\0’ ,但其所占的空间不计算在len中

四、SDS扩容策略
Redis做为数据库,经常被用于速度要求严苛、数据被频繁修改的场合。
所以 Redis 的 SDS 对空间 扩容或释放 不可能真的 频繁对 内存空间进行重新分配

SDS通过未使用空间解除了字符串长度和底层数组长度之间的关联
及 buf 的实际长度 = len + free + 1 (这个1 是 ‘\0’ 的空间 )

1.空间预分配
当SDS的API对一个SDS进行修改,并且需要对SDS进行空间扩展的时候,程序不仅会为SDS分配SDS分配修改所必须要的空间,还会为SDS分配额外的未使用空间。

分配空间的公式
1.如果SDS分配之后,SDS的实际长度(len)将小于1MB,
那么将分配和len长度相同大小的未使用空间,这个时候 len == free
buf 实际长度 = len + free + 1

2.如果SDS分配之后,SDS的实际长度(len)将大于等于 1MB,
那么程序会分配 1MB 的未使用空间,这个时候
free == 1MB
buf 实际长度 = len + 1MB + 1

优点:1.减少空间分配次数
缺点:1.可能会使用大量的空闲空间无法被使用
问题:
如果出现一次扩容特大的空间,是否会导致需要连续的进行
扩容?

2.惰性空间释放
当SDS需要缩短SDS保存的字符串时,不会立即进行空间释放操作,
而是 减少 len 的大小, 扩大 free 的大小,只有到真的需要释放空间的时候
再会对空间进行释放

五、二进制安全 binary-safe
由于SDS字符串结束标志 不是 ‘\0’ , 而是以 len 的长度做为 真实的长度标识。
所以 SDS 可以存储任何字符。
例如:
文本、图片、视频、音频、压缩文件这样的二进制数据

六、兼容传统的 字符串 函数操作

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值