当前位置:网站首页>Redis 入门-第一篇-数据结构与对象-简单动态字符串(SDS)
Redis 入门-第一篇-数据结构与对象-简单动态字符串(SDS)
2022-06-23 11:34:00 【tiger’s bytes】
简单动态字符串(simple dynamic string)(之后简称 SDS ) 是 Redis 的默认字符串表示,在 Redis 里面,C 字符串只会作为字符串字面量用在一些无须对字符串值进行修改的地方。
struct sdshdr {
int len; // 字节数组已使用的字节数,尾部的 '\0' 结束符不算在内,这个空字符对于用户来说是透明的,它的空间分配以及添加都是由 SDS 函数自动完成的,遵循尾部添加 '\0' 结束符的好处是,SDS 可以直接使用部分 C 字符串函数库里面的函数
int free; // 字节数组未使用的字节数
char buf[]; // 字节数组,用于保存 SDS
}SDS 可以在 O(1) 时间复杂度获取自身长度,同时在修改 SDS 内容时,SDS API 会自动检查 SDS 的字节数组是否足够存放本次修改后的内容,如果不够,API 会自动对其扩容,杜绝了缓冲区溢出的可能。
因为 C 字符串并不记录自身的长度,所以对于一个包含了 N 个字符的 C 字符串来说,这个字符串的底层实现总是一个 N + 1 个字符长的数组(额外的一个字符空间用于保存空字符 '\0' )。因为 C 字符串的长度和底层数组长度之间存在着这种关联性,所以每增长或缩短一个 C 字符串,程序总是要对保存着这个 C 字符串的底层数组进行一次内存重分配操作,否则就会产生内存溢出或内存泄漏。
在一般的程序中,如果修改字符串长度的情况不太常出现,那么每次修改都执行一次内存重分配是可以接受的,但是 Redis 作为数据库,经常被用于速度要求严苛、数据被频繁修改的场合,如果每次修改字符串都要执行一次内存重分配的话,那么光是执行内存重分配的时间都会占去修改字符串所用时间的一大部分,如果这种修改操作频繁发生的话,可能还会对性能造成影响。为了避免 C 字符串这种缺陷,SDS 通过未使用空间解除了字符串长度和底层数组长度之间的关联,在 SDS 中,buf 数组长度不一定就是字符数量加一,数组里可以包含未使用的字节,而这些字节的数量就由 SDS 的 free 属性记录,通过字节数组未使用字节数 (free) 这个成员变量,SDS 实现了空间预分配和惰性空间释放两种优化策略。
空间预分配用于优化 SDS 的字节数组增长操作,当 SDS 的 API 对一个 SDS 进行修改,并且需要扩容时,程序不仅会为 SDS 分配必须的空间,还为 SDS 分配空闲空间。其中,额外分配的空闲空间由如下策略决定:
- 如果扩容后 len 将小于 1 MB ,那么分配的空闲空间将和 len 的大小一样,即 free 等于 len,这时候 buf 数组的实际字节大小为 free + len + 1。
- 如果扩容后 len 将大于 1 MB ,那么分配的空闲空间为 1MB 大小。
惰性空间释放用于优化 SDS 的字符串缩短操作,当 SDS 的 API 需要缩短保存的字符串时,程序并不立即试用版内存重分配来回收多余的字节,而是使用 free 属性将这些字节的数量记录起来,并等待将来使用。与此同时,SDS 也提供了相应的 API ,让我们可以在有需要时,真正的释放 SDS 的空闲空间,所以不用担心惰性空间释放策略会造成内存浪费。
通过这种预分配策略,SDS 将连续增长 N 次字符串所需的内存重分配次数从必定 N 次降低为最多 N 次。此外,C 字符串中的字符必须符合某种编码,并且除了字符串末尾之外,字符串里面不能包含空字符,否则最先被程序读入的空字符将被误认为是字符串的结尾,这些限制使得 C 字符串只能保存文本数据,而不能保存图片、音频、视频、压缩文件等二进制数据。比如下面这样的字符串,用 C 字符串来保存的话后面的 ’Now‘ 就会被忽略掉。

因为 SDS 是靠 len 属性来判断是否读完 buf 数组中的所有字符的,所以不会存在 C 字符串这种问题,所以我们说 SDS 是二进制安全的,所有 SDS API 都会以处理二进制的方式来处理 SDS 存放在 buf 数组里的数据,程序不会对其中的数据做任何限制、过滤或假设,数据在写入时是什么样,在读出的时候就是什么样。这也是我们将 SDS 的 buf 属性称为字节数组的原因,因为 Redis 不是用这个数组来保存字符,而是保存一系列二进制数据。

表1.1 C 字符串和 SDS 之间的区别
C 字符串 SDS 获取字符串长度的时间复杂度为 O(N) 获取字符串长度的时间复杂度为 O(1) API 是不安全的,可能会造成缓冲区溢出或内存泄漏 API 是安全的,不会造成缓冲区溢出或内存泄漏 修改字符串长度 N 次必然要执行 N 次内存重分配 修改字符串长度 N 次最多要执行 N 次内存重分配 只能保存文本数据 可以保存文本或二进制数据 可以使用所有 <string.h> 库中的函数 可以使用部分 <string.h> 库中的函数
| C 字符串 | SDS |
|---|---|
| 获取字符串长度的时间复杂度为 O(N) | 获取字符串长度的时间复杂度为 O(1) |
| API 是不安全的,可能会造成缓冲区溢出或内存泄漏 | API 是安全的,不会造成缓冲区溢出或内存泄漏 |
| 修改字符串长度 N 次必然要执行 N 次内存重分配 | 修改字符串长度 N 次最多要执行 N 次内存重分配 |
| 只能保存文本数据 | 可以保存文本或二进制数据 |
| 可以使用所有 <string.h> 库中的函数 | 可以使用部分 <string.h> 库中的函数 |
边栏推荐
- 六张图详解LinkedList 源码解析
- Gary Marcus发文:AI研究者需要知道的三个来自语言学家的观点
- From 0 to 1, how does the IDE improve the efficiency of end-to-end R & D| DX R & D mode
- mysql,如何在使用存储过程计算最大值
- How Huawei cloud implements a global low latency network architecture for real-time audio and video
- Esp32-cam, esp8266, WiFi, Bluetooth, MCU, hotspot create embedded DNS server
- Groovy之Map操作
- Oversampling Series II: Fourier transform and signal-to-noise ratio
- Tensorrt笔记(四)推理分割模型
- 网上注册股票开户很困难么?现在网上开户安全么?
猜你喜欢

DevEco Device Tool 助力OpenHarmony設備開發

Force buckle 1319 Number of connected network operations

2光2电级联型光纤收发器千兆2光2电光纤收发器迷你嵌入式工业矿用本安型光纤收发器
Go zero micro Service Practice Series (VI. cache consistency assurance)

A child process is created in the program, and then the parent and child processes run independently. The parent process reads lowercase letters on the standard input device and writes them to the pip

Vone news | wanglian technology empowers the public to enjoy the self-organization management of the chain network, creating an enterprise level alliance Dao

Design and implementation of stm32f103zet6 single chip microcomputer dual serial port mutual sending program

Tamidog | analysis of investor types and enterprise investment types

Android security / reverse interview questions

汉源高科1路非压缩4K-DVI光端机4K高清非压缩DVI转光纤4K-DVI高清视频光端机
随机推荐
十大劵商如何开户?在线开户安全么?
How to use note taking software flowus and note for interval repetition? Based on formula template
Introduction and use of vector
Android security / reverse interview questions
Leetcode 1209. 删除字符串中的所有相邻重复项 II(牛逼,终于过了)
quarkus+saas多租户动态数据源切换实现简单完美
【云驻共创】华为云HCIA-IoT V2.5培训系列内容之物联网概览
运行时应用自我保护(RASP):应用安全的自我修养
哪个券商公司开户是最靠谱安全的
Introduction to Huawei cloud maintenance and sharing exchange platform
The simplest DIY actuator cluster control program based on 51 single chip microcomputer, pca9685, IIC and PTZ
在工作中学习的三个方法
More than observation | Alibaba cloud observable suite officially released
一张图解码 OpenCloudOS 社区开放日
4路电话+1路千兆以太网4路PCM电话光端机
Deep analysis and Simulation of list
如何使用笔记软件 FlowUs、Notion 进行间隔重复?基于公式模版
Oversampling Series III: quantization error and oversampling rate
Video data annotation tools and platforms (data annotation company)
Maui uses Masa blazor component library