SDS(simple dynamic string),简单动态字符串。s同时它被称为 Hacking String。hack 的地方就在 sds 保存了字符串的长度以及剩余空间。sds 的实现在 sds.c 中。

C语言字符串使用长度为n+1的字符数组来表示长度为n的字符串,并且字符数组的最后一个元素总是空字符'\0',这样的方式存储,时存在安全隐患的,并且它不能满足效率方面的需求。

因此Redis没有使用C原生的string而是自己构建了SDS。在Redis里,C语言字符串只用于一些无须对字符串值进行修改的地方,比如:日志。

在Redis中,包含字符串值的键值对都是使用SDS实现的,除此之外,SDS还被用于AOF缓冲区、客户端状态的输入缓冲区。

SDS定义

struct sdshdr{
//字节数组
char buf[];
//buf数组中已使用字节数量
int len;
//buf数组中未使用字节数量
int free;
}

如上图所示,len表示该SDS保存了一个6字节长度(不包含结束符)的字符串,free表示该SDS还有6个字节的未使用空间,buf是一个char类型的数组 ,保存了该SDS所存储的字符串值。

高效

相比C语言字符串,使获取字符串长度时间复杂度降为O(1)而C原生的获取长度为O(N) 遍历整个数组。

安全

同时SDS杜绝缓冲区溢出,不会像C那样造成数组数据不安全,绝对不会越界。

当需要对SDS进行修改时,API会先检查SDS当前剩余空间是否满足修改之后所需的空间,如果不满足的话API会自动将SDS的空间扩展至足够用的空间然后才进行下一步操作,所以SDS不会出现缓冲区溢出问题。

减少内存分配

C语言字原生符串底层是使用一个n+1个字符长度的char类型数据实现的,所以每次增长或缩短一个原生字符串,程序都要对这个字符串数组进行一次内存重分配操作:

同时因为内存重分配涉及复杂的算法,并且可能需要执行系统调用,所以它通常是一个比较耗时的操作。Redis经常被用于速度要求严苛、数据被频繁修改的场合,如果每次修改字符串都需要执行一次内存重分配的话,那么对于性能会造成很大影响。

SDS 在分配了内存之后(往往空间会存在盈余,也就是空间的预分配),然后自己通过len 和 free 来维护已使用的和未使用的内存,不再依赖系统来重新划分,这样能有效的提升性能。

空间预分配

用于字符串增长操作,当字符串增长时,程序会先检查需不需要对SDS空间进行扩展,如果需要扩展,程序不仅会为SDS分配修改所必要的空间,还会为SDS分配额外的未使用空间,额外分配的未使用空间公式如下:

SDS空间 < 1MB

如果对SDS修改之后,SDS的长度(修改之后len属性的值)小于1MB,那么则分配和len属性同样大小的未使用空间,这时SDS的len属性和free属性的值相同。如:如果修改之后SDS的len将变为10字节,那么程序也会分配10字节的未使用空间,SDS的buf数组实际长度变为10 + 10 + 1 = 21(额外一个字节用于保存结束符\n)

SDS空间 > 1MB

如果对SDS修改之后,SDS的长度大于等于1MB,那么程序会分配1MB的未使用空间。如:修改之后的len将变为10MB,那么程序会分配1MB的未使用空间,SDS的bug数组长度为10MB + 1MB + 1byte

SDS空间 > 512MB

Game over~ 报错!

惰性空间释放

用于优化SDS的字符串收缩操作,当字符串收缩时,程序不会立即执行内存重分配来回收收缩后内存多出来的空间,而是使用free属性记录下来,以备将来使用。

通过空间预分配,Redis可以减少连续执行字符串增长操作所需的内存重分配次数,通过惰性空间释放,SDS避免了缩短字符串时所需的内存重分配操作,并为将来由可能的增长操作提供了优化。

Redis 数据结构 之 SDS的更多相关文章

  1. Redis数据结构之sds基本操作函数

    本文及后续文章,Redis版本均是v3.2.8 本篇文章讲解sds基本操作函数,我们从源码角度来进一步理解. 一.sds创建函数和销毁 sds创建函数 /* Create a new sds stri ...

  2. Redis—数据结构之sds

    Redis是一个Key Value数据库.Redis有5种数据类型:字符串.列表.哈希.集合.有序集合.而字符串的底层实现方法之一就是使用sds.以下描述中请读者注意区分sds是指简单动态字符串这一数 ...

  3. Redis数据结构:SDS

    1. 简单动态字符串(simple dynamic string,SDS)是Redis的默认字符串表示结构,底层的string都是基于SDS实现.Redis基于C语言,并引用了部分C函数. 使用场景: ...

  4. redis数据结构存储SDS设计细节(redis的设计与实现笔记)

    redis虽说是用C语言开发的,但是redis考虑了性能.安全性.效率性.功能等要,redis底层存储字符串实现,自己实现了名为简单动态字符串(Simple dynamic string)简称SDS的 ...

  5. redis数据结构之SDS

    简介 redis源码虽然是C语言实现的,但是Redis没有直接采用C语言传统的字符串表示,而是构建了一种名叫简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SDS用 ...

  6. Redis数据结构之robj

    本文及后续文章,Redis版本均是v3.2.8 我们知道一个database内的这个映射关系是用一个dict来维护的.dict的key固定用一种数据结构来表达,这这数据结构就是动态字符串sds.而va ...

  7. Redis 的底层数据结构(SDS和链表)

    Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件.可能几乎所有的线上项目都会使用到 Redis,无论你是做缓存.或是用作消息中间件,用起来很简单方便 ...

  8. 深入理解Redis 数据结构—简单动态字符串sds

    Redis是用ANSI C语言编写的,它是一个高性能的key-value数据库,它可以作用在数据库.缓存和消息中间件.其中 Redis 键值对中的键都是 string 类型,而键值对中的值也是有 st ...

  9. Redis数据结构底层知识总结

    Redis数据结构底层总结 本篇文章是基于作者黄建宏写的书Redis设计与实现而做的笔记 数据结构与对象 Redis中数据结构的底层实现包括以下对象: 对象 解释 简单动态字符串 字符串的底层实现 链 ...

随机推荐

  1. web自动化之浏览器的窗口切换

    from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from seleni ...

  2. Python操作Word与Excel并打包

    安装模块 # Word操作库 pip install docx # Excel操作库 pip install openpyxl # 打包exe工具 pip install pyinstaller Wo ...

  3. java类的方法的使用

    类的方法:提供某种功能的实现: 实例:public void eat (){ } public String  getName(){ } public void  setName(String n){ ...

  4. scikit-learn中文文档

    http://sklearn.apachecn.org/cn/0.19.0/tutorial/statistical_inference/supervised_learning.html

  5. AVIRIS 简介

    AVIRIS 是指 机载可见光近红外成像光谱(Airborne Visible InfraRed Imaging Spectrometer).是由美国NASA下属的喷气动力实验室(JPL)开发和维护的 ...

  6. 线程池续:你必须要知道的线程池submit()实现原理之FutureTask!

    前言 上一篇内容写了Java中线程池的实现原理及源码分析,说好的是实实在在的大满足,想通过一篇文章让大家对线程池有个透彻的了解,但是文章写完总觉得还缺点什么? 上篇文章只提到线程提交的execute( ...

  7. Rocket - regmapper - RegField

    https://mp.weixin.qq.com/s/7WKB1QxcVzqm2Q7bWcKHzA 简单介绍RegField的实现. 1. 简单介绍 定义寄存器域相关的参数类型. 2. RegFiel ...

  8. Rocket - tilelink - mask

    https://mp.weixin.qq.com/s/Gqv09RIgSSg5VKe-wb4aGg   讨论tilelink中使用MaskGen生成mask的用法.   1. tilelink中的ma ...

  9. 跨域解决方案 - JSONP

    目录 1. 定义 2. JSONP 解决跨域 3. 应用场景 4. 代码演示 1. 定义 在HTML 中, script 标签有两个个性质: script 标签可以不受同源策略的限制去访问服务器资源, ...

  10. 如何从0创建一个react项目

    1. 确保本机电脑安装了yarn和node: 2. 在需要安装的文件夹目录下输入:create-react-app  +(项目名称): PS:上图使用的软件为webStorm 3. 此时一个简单的re ...