阿里面试官问我:“Redis 的 String 底层是怎么设计的?”,我画完 SDS,他点了点头……

今天分享一道高频面试题:

Redis 中的 String 底层是怎么设计的?

平时使用 SETGET 时,我们很少关心 Redis 是怎么保存字符串的。看起来只是存进去一个值,再原样取出来,没什么特别的。

但 Redis 的 String 不只可以保存普通文本。比如数字、JSON、序列化对象,甚至图片的二进制内容,都可以作为 String 保存。

这一切都和 Redis 自己实现的字符串结构 SDS 有关。

Redis 的 String 类型最基本的数据类型,它能够存储任何二进制数据

Redis 的 String 类型底层实现是基于一个名为 SDS(Simple Dynamic String,简单动态字符串数据结构。SDS 提供了对动态字符串的操作,它的设计目标是能够高效地处理字符串,同时尽可能地降低内存重新分配的次数。

下面是 SDS 的头部结构源代码

c 复制代码
typedef char *sds;

struct sdshdr {

    // 已用长度
    int len;

    // 可用长度
    int free;

    // 保存字符串的字节数组
    char buf[];
};

SDS 的数据结构如下:

包含以下几个部分:

  • free: 表示字符串的可用长度,也就是字符串中可以增加的字符数量,而不需要进行内存重新分配。
  • len: 表示字符串的占用长度,也就是字符串中实际字符的数量。
  • buf: 是一个字节数组,用于存储实际的字符串。这个数组的长度是 len + free + 1,多出来的 1 是为了存储字符串的结束符 '\0',用于兼容部分 C 语言标准库的函数。

和普通的 C 字符串相比,SDS 有一个很直接的优势:获取长度时不用从头遍历

因为长度已经记录在 len 字段中,所以读取字符串长度的时间复杂度O(1)。即使字符串很长,也可以直接拿到结果。

另外,free 字段则给字符串预留了一部分可用空间。一般在追加内容时,只要预留空间足够,Redis 就可以直接写入,不必每次都申请一块新内存,再复制原有数据。

所以,Redis 的 String 看起来简单,底层实现却很讲究。

SDS 通过保存长度、记录可用空间和使用字节数组,解决了普通 C 字符串在长度计算、二进制数据处理和内存扩容方面的问题。

相关推荐
IT_陈寒几秒前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
分支预测失败6 分钟前
RISC-V 时间子系统深度专题:mtime 访问路径、SBI 定时器与 Linux tickless 协同
后端
65岁退休Coder12 分钟前
PI Agent 开发一个生产级 Harness
后端·node.js·agent
用户83562907805131 分钟前
如何使用 Python 给 Word 文档添加水印
后端·python
一个风轻云淡1 小时前
Markdown学习与实践
后端
程序员cxuan2 小时前
真没想到,AI 圈又杀出来一匹黑马!
人工智能·后端·程序员
掘金者阿豪2 小时前
极空间 NAS 部署 Typecho:从 Docker 安装、主题配置到固定公网访问
后端
科技苑2 小时前
前后端分离与微服务架构如何协同?
前端·后端·前端框架
Lambert2812 小时前
AgentScope Java 从零(07):官方有权限引擎,我却在工具里写了个 if
java·后端·ai编程
Ticnix2 小时前
多租户 RAG:让每个用户只检索到自己的知识库
后端·python·agent