当前位置: 首页 > news >正文

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 来实现的原因~

http://www.xdnf.cn/news/1425709.html

相关文章:

  • 区块链存证中的隐私保护
  • C++ 用于运行时类型识别的typeinfo库使用指南
  • 基于STICS模型的黄土高原苹果园生态
  • 众擎机器人开源代码解读
  • 从物理模拟器和世界模型中学习具身智能
  • 【算法专题训练】17、双向链表
  • 开源项目硬核应用:AntPathMatcher实战
  • 【文件IO和部分标准IO】输入输出缓冲区和报错
  • 信创之-麒麟v10服务器安装tengine(已完成)
  • 005 从会议全貌到模型本质:会议介绍与语言模型概述的深度融合
  • 电源相关零碎知识总结
  • 深度学习——速问速答
  • shell脚本函数介绍
  • http缓存
  • LobeChat知识库,小团队的选择,理解Embedding与向量数据库的关系
  • 解决Content Security Policy (CSP)问题
  • Java类加载机制
  • 软件使用教程(四):Jupyter Notebook 终极使用指南
  • 【iOS】关键字复习
  • javaScript变量命名规则
  • MySQL基础知识保姆级教程(四)视图与约束
  • Chrome 如何清除浏览器缓存
  • 【开题答辩全过程】以 基于SpringBoot的校园一卡通管理系统的设计与实现为例,包含答辩的问题和答案
  • ESP32驱动数字麦克风INMP441
  • A2A + MCP 的python实现的最小可运行骨架
  • Jmeter实现参数化的4种方式
  • 构建AI智能体:二十、妙笔生花:Gradio集成DashScope Qwen-Image模型实现文生图
  • 人脸识别备案的重要意义
  • ES6新特性:JavaScript的进化装备箱[特殊字符]
  • 记一次使用函数式接口