大家好,我是R哥。

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

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

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

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

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

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

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

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

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

好了,今天的分享就到这里了,后续R哥也会继续关注并分享更多的 Java 技术资讯和干货,关注公众号Java技术栈第一时间推送。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注