Redis 的 SDS:像橡皮筋笔记本一样好用的字符串

目录

从传统字符串的痛点说起​

两种字符串的本质区别​

SDS 的智能设计:让笔记本更懂你​

神奇的 "双标签" 系统​

空间预分配:提前留好备用纸​

惰性空间释放:不撕纸的智慧​

二进制安全:完整记录所有符号​

兼容旧工具:隐藏的小标记​

揭开 SDS 的结构面纱​

实际例子:SET msg "hello" 背后的结构​

从传统字符串的痛点说起​

想象你用两种笔记本记账:

  • 传统 C 字符串就像明信片,写完不能改,想加内容必须换张新的重写;查字数得逐个清点;遇到句号就停笔,后面内容全丢。
  • 而 Redis 发明的 SDS(简单动态字符串)就像带橡皮筋的智能笔记本,能自动伸缩、随时查字数、完整记录所有内容 —— 这就是 Redis 为什么把 SDS 作为默认字符串表示的原因。​

两种字符串的本质区别​

问题场景​

明信片(C 字符串)​

橡皮筋笔记本(SDS)​

改内容​

必须换张新的重写​

直接改,不够长自动拉长​

查长度​

逐个字数,费时间​

封面直接标着数字​

写太多​

内容会写到别人的纸上(缓冲区溢出)​

自动加纸,绝不越界​

特殊符号​

遇到句号就停笔​

完整记录所有内容​

SDS 的智能设计:让笔记本更懂你​

神奇的 "双标签" 系统​

SDS 笔记本封面有两个关键标签:​

  • len(已写页数):直接标着内容长度,查字数不用逐页翻(O (1) 复杂度)​
  • free(空白页数):记录还能写多少字,避免空间不足的尴尬​

这对标签就像笔记本的智能导航系统,让 Redis 随时知道内容有多长、还能加多少内容。​

空间预分配:提前留好备用纸​

创建 SDS 时会自动预留空白页:​

  • 记短内容(如 "msg"3 个字符)时,按 1:1 预留空白(len=3,free=3)​
  • 就像写日记时多留几页,下次加内容不用换本子​
  • 内容超过 1MB 时,固定留 1MB 空白(比如 20MB 内容只留 1MB 空白)​
  • 就像搬家时小箱子留同等空间,集装箱则固定留一个小箱子空间,避免浪费​

这种设计通过sdsMakeRoomFor函数实现,能大幅减少换本子(内存分配)的次数。​

惰性空间释放:不撕纸的智慧​

缩短内容时,SDS 不会马上撕掉多余的纸:​

  • 把 "msg" 改成 "m" 后,len 变成 1,原来的空间变成空白(free=5)​
  • 就像擦掉写错的字但不撕页,空白留着下次用​
  • 需要时可调用sdsRemoveFreeSpace函数手动释放空白空间​

这种 "不浪费空白" 的设计,避免了频繁调整本子厚度(内存重分配)的麻烦。​

二进制安全:完整记录所有符号​

C 字符串遇到句号(\0)就停笔,而 SDS 靠 len 判断结束:​

  • 记 "m. sg" 时,C 只会记到 "m",SDS 则完整保存全部内容​
  • 就像录音笔会记录整首歌,包括中间的停顿​
  • 不管内容里有什么特殊符号,都能原样保存和读取​

兼容旧工具:隐藏的小标记​

虽然 SDS 靠 len 判断结束,但每个本子最后还是会偷偷画个小三角(\0):​

  • 这个标记不占 len 计数,也不影响内容​
  • 却能兼容传统 C 语言的阅读工具​
  • 就像笔记本最后留一页空白做标记,方便用旧书签查找​

揭开 SDS 的结构面纱​

这些智能设计在代码中是这样实现的:​

struct sdshdr {​

    int len; // 已写内容长度(已写页数)​

    int free; // 空白长度(空白页数)​

    char buf[]; // 内容数组(内页纸)​

};​

实际例子:SET msg "hello" 背后的结构​

执行SET msg "hello"后,会创建两个 SDS 对象:​

  1. 键 "msg" 的 SDS 结构:​
  • len=3("msg" 有 3 个字符)​
  • free=3(按 1:1 预分配空白)​
  • buf=['m','s','g','\0'](最后是隐藏标记)​
  1. 值 "hello" 的 SDS 结构:​
  • len=5("hello" 有 5 个字符)​
  • free=5(预分配 5 个空白)​
  • buf=['h','e','l','l','o','\0']​

注意:空白页(free)为 0 时,表示这个 SDS 没有预留任何空白空间,下次修改必须分配新空间。​

        SDS 就像一本懂你习惯的智能笔记本,用贴心的设计解决了传统笔记本的各种麻烦。它通过 "提前备货" 和 "不浪费空白" 的空间管理策略,加上 "完整记录" 和 "兼容旧工具" 的实用设计,让 Redis 处理数据时又快又安全 —— 这就是为什么 Redis 里几乎所有需要修改的字符串,都用 SDS 来实现的原因~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值