Redis | 源码阅读 —— 字符串

Redis中的字符串采用SDS结构,它结合了C语言字符串特性和二进制安全特性,提供了高效且安全的字符串操作。SDS在获取长度、连接、拷贝等操作上具有O(1)的时间复杂度,通过空间预分配和惰性释放策略减少内存分配次数,提升性能。此外,SDS还兼容C语言字符串,支持追加任意二进制数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

目录

一、SDS 结构体

二、获取字符串的长度

三、字符串的连接与拷贝

四、二进制安全特性

五、兼容 C 字符串

六、SDS 空间的分配与释放

1、空间预分配

2、惰性空间释放

七、最后


     使用过 Redis 的都知道 Redis 用的最多的可能是它的 Key/Value 的缓存,在 Redis 用作 Key/Value 的缓存时,Value 有若干种数据类型,分别是 String、List、Set、Sorted Set 和 Hash。不同的 Value 类型对应了不同的数据结构,我们分别来了解一下 Redis 各种 Value 类型的数据结构。

        这次先来了解一下,Redis 的 String 类型所对应的数据结构。我这里要首先感谢《Redis 设计与实现》一书的作者 黄健宏 先生,他写出如此优秀的书籍从而让我们能够学习高性能的 Redis 的内部实现原理。

       Redis 是使用 C 语言实现的,C 语言本身就是一种运行时非常高效的程序设计语言。但是 Redis 的字符串结构并没有沿用 C 语言常规的存储字符串的方式。在 C 语言中,字符串是以数组的形式存储在内存中的,并且以 \0 作为字符串的结尾。在 C 语言中,读取字符串、计算字符串长度、连接字符串、拷贝字符串等函数,都是以 \0 来进行判断,而如果在写代码时对缓冲区检查不严格,则会导致缓冲区溢出。缓冲区溢出这种安全问题也是 C 语言一个很严重的问题。C 语言设计的初衷是希望把尽可能多的控制权交给程序员来保证 C 语言的灵活和自由,但是灵活和自由的同时也付出了很多惨痛的代价。

       当然了,上面的存储方式是 C 语言的方式,其他的语言就未必了,如果使用过 Delphi 的话,就知道 Delphi 的字符串就不是以 \0 作为结束的,而是在字符串的开头位置放入了字符串长度一个标识。

        现在,我们来看看 Redis 的实现,我这里是 Redis 2.6 的实现源码(版本低一些,阅读时会相对容易一些)。

一、SDS 结构体

        在 Redis 中的字符串是结合了 C 语言字符串特性(即以 \0 结尾)和一种被称为 SDS 的数据结构共存的字符串结构,其结构的定义在 sds.h 的头文件中,该数据结构的定义如下(所有的中文注释都是我注释的,官方源码中是不可能提供中文注释的,如果注释有误希望可以指出):

struct sdshdr {
    /* 已使用缓冲区的长度 */
    int len;
    /* 未使用缓冲区的长度 */
    int free;
    /* 缓冲区 */
    char buf[];
};

        该结构体中包含三个成员,分别是 len、free 和 buf,其中 len 用来保存已经使用的缓冲区的长度,free 用来保存未使用的缓冲区的长度,buf 是真正的缓冲区的字符数组。buf 中存储的字符串仍然是以 \0 结尾,但是它的长度并不计算在 len 中,这一点和 C 语言是相同的,使用 strlen 计算字符串长度的时候,也没有把 \0 计算在内。

        确定了数据结构以后,所有的操作就是围绕数据结构来展开了,就好比我们写代码,确定了表结构,生成了实体类,然后业务处理就是围绕输入和针对实体类的具体操作了。

二、获取字符串的长度

        在 C 语言中,求字符串的长度是逐个字符进行遍历统计,直到遇到 \0 就是字符串的结束,这样就能得到字符串的长度了。也就是说,在 C 语言中获取字符串长度的时间复杂度为 O(n)。

        在 SDS 结构体中,获取字符串的长度的时间复杂度则为 O(1),因为在 SDS 结构体中已经有一个成员来保存已使用缓冲区的长度了,它就是实际意义上的字符串的长度,因此在 SDS 字符串长度的时

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农UP2U

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值