redis 设计与实现 读书笔记 - 简单动态字符串

1. 简单动态字符串(SDS)

1.1 SDS 定义

     

 

1.2 SDS与C字符串的区别

1.2.1 获取字符串长度

C字符串中没有SDS结构中的len属性,那么在获取字符串的长度时,每次都需要遍历字符串,直到遇到结尾的 '\0'。但SDS中有len属性。

1.2.2 杜绝缓冲区溢出

SDS结构的字符串在进行修改时,会先判断字符串自身长度,同时根据后设置的字符串进行计算,自动扩展字符串长度。但是C字符串如果在修改前没有人为判断并修改长度,会占用相邻字符串的内容。

 

 

 如果将上图中的s1字符串,由Redis 修改为 Redis Cluster ,如果没有为s1分配足够的空间,那么结果如下所示:S1的内容溢出到S2所在的位置上。

 

 

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

基于1.2.2的特殊,C字符串每次增加或截取时,都需要重新进行内存分配,但是SDS通过未使用空间,解除了字符串长度和底层数组长度之间的关联。

在SDS中,buf 数组的可以包含未使用字符,未使用字符数据由 free 属性记录。

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

 1.空间预分配(优化字符串增长时,内存分配次数)

   对SDS字符串进行修改时

   1.1如果SDS的长度(len属性)< 1MB,那么 free = len , buf数组实际长度= len + free + 1byte ('\n'结尾)

 1.2如果SDS的长度 (len属性)>= 1MB ,那么 free = 1MB ,buf 数组实际长度 = len + free(1MB) +1byte('\n'结尾)

2. 惰性空间释放(优化字符串缩短时,内存分配次数)

 即缩短SDS字符串时,并不会立即释放被缩短的空间,而是使用未使用空间,保留在SDS里面,为将来有可能的增长提供了优化,即增长时,如未超过未使用空间,同样不需要重新分配内存。

并且提供了相应的API,可以在需要时,进行空间释放,避免造成内存浪费。

1.2.4 二进制安全

即SDS 所有的API都会以处理二进制的方式处理SDS存放在buf 里的数据,数据在写入时什么样,被读取时就是什么样. 

redis 不是用buf 数组保存字符,而是保存二进制数据。

posted @   C兔  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示