阿里面试官问我:“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 字符串在长度计算、二进制数据处理和内存扩容方面的问题。

相关推荐
东风破_4 小时前
从输入 juejin.cn 到看到页面:DNS、Nginx、服务器集群与 CDN 到底在做什么?
后端·mysql
东风破_4 小时前
从 0 设计一个博客数据库:用户、头像与文章表应该怎么建?
后端·mysql
大鸡腿同学5 小时前
黄仁勋点透的 AI 真相:能实现你知道但做不到的,却实现不了你不知道的
后端
FfHUCisI5 小时前
Go 编译过程全景
开发语言·后端·golang
FfHUCisI5 小时前
Golang 语法分析与 AST:Parser 与 go/ast
开发语言·后端·golang
++==7 小时前
RESTful详解:核心思想、框架、与HTTP的区别,API的设计风格
后端·http·restful
IT_陈寒8 小时前
Vue的响应式更新有时候真的不听话
前端·人工智能·后端
向生9 小时前
Ubuntu Caddy 保姆级完整教程
后端
tntxia9 小时前
Docker权限的问题
后端
明月_清风9 小时前
看完这段关于"全插件化架构"的技术分析后,我整理了一份笔记
前端·后端