展开

关键词

聊聊Redis SDS

Redis面试中经常被问到,Redis效率为什么这么快,很多同学往往回答:① Redis基于内存操作;② Redis是单线程的,采用了IO多路复用技术;③ Redis未使用C语言字符串,使用了SDS字符串 C语言字符串使用长度为n+1的字符数组来表示长度为n的字符串,并且字符数组的最后一个元素总是空字符0,因为这种字符串表示方式不能满足Redis对字符串在安全性、效率以及功能方面的要求,所以Redis自己构建了 在Redis里,C语言字符串只用于一些无须对字符串值进行修改的地方,比如:日志。在Redis中,包含字符串值的键值对都是使用SDS实现的,除此之外,SDS还被用于AOF缓冲区、客户端状态的输入缓冲区。 SDS定义struct sdshdr{ 字节数组 char buf,s2的值为Memcache,底层数组的值为,在C语言中如果要执行strcat(s1, cluster)把s1修改为Redis cluster 通过空间预分配,Redis可以减少连续执行字符串增长操作所需的内存重分配次数,通过惰性空间释放,SDS避免了缩短字符串时所需的内存重分配操作,并为将来由可能的增长操作提供了优化。

1.5K20

Redis SDS 深入一点,看到更多!

1、什么是SDS?Redis 自定的字符串存储结构,关于redis,你需要了解的几点!中我们对此有过简要说明。 Redis 底层是用C语言编写的,可是在字符存储上,并未使用C原生的String类型,而是定义了自己的字符串结构 Simple Dynamic Stirng,简称SDS。 buf的这种遵循C语言形式的存储,使得Redis可以直接使用C语言的相关字符串函数进行SDS对象的操作。 二、SDS的优势1、O(1)时间复杂度获取字符串长度SDS内部维护着一个字符串长度的len变量,可以直接读取,时间复杂度为O(1)。 针对此弊端,RedisSDS内存配置策略上采用了空间预分配+惰性删除相结合的策略。a)空间预分配:空间预分配用于优化SDS字符扩展操作。

35120
  • 广告
    关闭

    云产品限时秒杀

    云服务器1核2G首年38元,还有多款热门云产品满足您的上云需求

  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    redis学习 - sds字符串

    redis学习 - sds字符串Redis 设计与实现:如果想要知道redis底层,这本书可以给予不少的帮助,非常推荐每一位学习redis的同学去翻一翻。 0x7fd75e44d370 refcount:2147483647 encoding:int serializedlength:2 lru:14294440 lru_seconds_idle:9 所以Redis 至于这三者有什么区别,可以直接看书:http:redisbook.compreviewobjectstring.html为什么redis string 要使用sds字符串? redissds是如何实现的由于c语言的string是以0结尾的Redis单独封装了SDS简单动态字符串结构,如果在字符串变量十分多的情况下,会浪费十分多的内存空间,同时为了减少malloc操作,redis 封装了自己的sds字符串。

    8310

    Redis string之SDS 源码分析 1

    string是Redis中最经常使用的一种结构,与c语言中的原生字符串不太一样,Redis 使用的是一种叫做SDS的结构,simple Dynamic string 粗暴点就是简单动态字符串,跟字面意思一样 ,sds能够动态的自己增加空间,扩容是无需使用者来操作的(相对于c 中的字符串)。 Redissds有两种版本,一种是3.2之前的,这个也是那本《Redis设计与实现》所说的方式,但是就现状来说实效性已经没有那么强了,大家注意区分。 那Redis 中设计的这个sds 有什么优势和缺点呢? 一次连续分配(Header + String + Null),对于一个sds它的各个部分总是内存连续的。缺点:1、sds 经常即是参数也是返回值,所以内部发生了什么是否重新分了空间等我们都是不知道的。

    34020

    redis源码之SDS

    1:SDS介绍我们在redis中执行命令set key name的时候,key和name都是字符串类型,而且字符串(string)在redis中是会经常用到的类型,那redis是如何保存字符串的呢? 我们接下来往下看 众所周知,redis是c写的,在c中使用char来保存字符串,并且用0作为字符串的结尾,但是redis不是这样保存的,redis是使用一种叫SDS的结构来保存字符串的。 4:兼容c语言函数库 (字符串后面会自动加上0)3.2版本以后的SDS结构前面的len和free以及char这种结构看起来很好,但是是存在一定的问题的 struct sdshdr{ int len; int

    16840

    Redis系列——8.SDS

    01前言从今天开始我们就要学习redis的源码了,想想还有点小激动呢。前方高能预警,非战斗人员迅速撤离。但是咱怎么能怂呢,撤离啥啊,说干就干,死磕源码,这代码也是人写的,他还能整出什么幺蛾子。 又一个但是来了,redis底层是用C语言写的,如果对C语言一窍不通,那还是算了,前方等待的是一座大山。墙裂推荐去了解一下C.emmmm,幸好我会C,哈哈哈,毕竟他是开启偶代码之路的小哥哥。 02介绍Redis没有直接使用C语言传统的字符串来表示(以空字符串结尾的字符数组),而是自己构造了一种名为简单动态字符串SDS。之前看的String类型的数据结构底层就是用SDS实现的。 SDSHDR(SDS的表头结构如下): struct sdshdr { int len; buf中已占用空间的长度 int free; buf中剩余可用空间的长度 char buf的数组,分配了(len +1+free)个字节的长度,前len个字节保存redis这5个字符串,接下来1个字节保存了0,剩下的free个字节未使用。

    16420

    Redis string之SDS源码分析2

    上一篇我们看了Redis里面关于新旧版本对于sds的不同的结构体实现,接下来看看sds.c中关于redis动态字符串的具体操作。从new开始:sdsnew函数是创建一个sds字符串的开始函数。? 先看一下函数注释的意思,就是说使用给定的字符串长度作为初始化值来创建一个sds动态字符串,如果是Null的话,那就给0字节,最后说了下sds是二进制安全的,我们可以放心的使用0。 下面来看一下这个函数:srcsds.c L:197当出现现有可用空间无法满足新串长度时进行扩容入参:sds s:带扩容的sds字符串指针、size_t addlen:新串的长度出参:新的sds指针,如果没发生扩容和入参是一致的 SDS_TYPE_5,则直接分配SDS_TYPE_8类型4、如果类型没有发生变化则重新开辟一块内存将原先整个SDS拷贝一份过去即可? image.png其他的另外几个函数都是依赖于这几个核心函数的,现在应该对SDS有了更深一步的理解啦。

    17510

    Redis源码剖析之SDS(Simple Dynamic String)

    SDS(simple dynamic string)是Redis提供的字符串的封装,在redis中也是存在最广泛的数据结构,它也是很多其他数据结构的基础,所以才选择先介绍SDSRedissds相关的源码都在srcsds.c 和srcsds.h中(链接可以直接跳转到我中文注释版redis源码),其中sds.h中定义了所有SDS的api,当然也实现了部分几个api,比如sds长度 正是因为预留空间的机制,所以redis需要记录下来已分配和总空间大小,当然可用空间可用直接算出来。 ?下一个问题,为什么redis费心费力要提供sdshdr5到sdshdr64这五种SDS呢? 我觉着这只能说明Redis作者抠内存抠到机制,牺牲了代码的简洁性换取了每个sds省下来的几个字节的内存空间。 本文是Redis源码剖析系列博文,同时也有与之对应的Redis中文注释版,有想深入学习Redis的同学,欢迎star和关注。

    18520

    跟着大彬读源码 - Redis 7 - 对象编码之简单动态字符串

    Redis 没有直接使用 C 语言传统的字符串表示(以空字符串结尾的字符数组),而是构建了一种名为简单动态字符串(simple dynamic string)的抽象类型,并将 SDS 用作 RedisRedis 就会适应 SDS 来表示字符串。 C 语言使用的这种字符串表示方式,并不能满足 Redis 对字符串再安全性、效率及功能方面的要求。因此,Redis 设计出了 SDS,来满足自己的相关需求。 通过使用 SDSRedis 将获取字符串长度所需的复杂度从 O(N) 降低到了 O(1),确保了获取字符串长度的工作不会成为 Redis 的性能瓶颈。 此外,SDS 也提供了相应的 API,让我们在有需要时,真正的释放 SDS 的未使用空间,避免造成内存浪费。总结Redis 只会使用 C 字符串作为字面量,大多数情况下,使用 SDS 作为字符串表示。

    17410

    Redis剖析——Redis字符串的设计与实现

    sds我们知道,C语言中将空字符结尾的字符数组作为字符串,而Redis对此做了扩展,定义了字符串类型sds(Simple Dynamic String)。 对于不同长度的字符串,Redis定义了不同的sds结构体:typedef char *sds; struct __attribute__ ((__packed__)) sdshdr5 { unsigned 由于该属性记录了字符串长度,所以sds可以在常数时间内获取字符串长度。Redis限制了字符串的最大长度不能超过512MB。alloc:已申请字节长度,即sds总长度。 【5】注意,sds实际上就是char*的别名,这里返回的s指针指向sdshdr.buf属性,即字符串内容。Redis通过该指针可以直接读写字符串数据。 sdsRedis定义的字符串类型,支持二进制安全、扩容。sds可以在常数时间内获取字符串长度,并使用预分配内存机制减少内存拷贝次数。 Redis对数据编码的主要目的是最大限度地节省内存。

    23020

    可能是目前最详细的Redis内存模型及应用解读

    本文主要介绍以3.0为例的Redis的内存模型,包括:Redis占用内存的情况及如何查询、不同的对象类型在内存中的编码方式、内存分配器(jemalloc)、简单动态字符串(SDS)、RedisObject 图片来源:《Redis设计与实现》通过SDS的结构可以看出,buf数组的长度=free+len+1(其中1表示字符串结尾的空字符);所以,一个SDS结构占据的空间为:free所占长度+len所占长度+ (2)SDS与C字符串的比较SDS在C字符串的基础上加入了free和len字段,带来了很多好处:获取字符串长度:SDS是O(1),C字符串是O(n)。 此外,由于SDS中的buf仍然使用了C字符串(即以‘0’结尾),因此SDS可以使用C字符串库中的部分函数。 但是需要注意的是,只有当SDS用来存储文本数据时才可以这样使用,在存储二进制数据时则不行(‘0’不一定是结尾)。(3)SDS与C字符串的应用Redis在存储对象时,一律使用SDS代替C字符串。

    39110

    精讲Redis内存模型一、Redis内存统计二、Redis内存划分三、Redis数据存储的细节四、Redis的对象类型与内部编码五、应用举例

    这篇文章主要介绍Redis的内存模型(以3.0为例),包括Redis占用内存的情况及如何查询、不同的对象类型在内存中的编码方式、内存分配器(jemalloc)、简单动态字符串(SDS)、RedisObject (2)SDS与C字符串的比较SDS在C字符串的基础上加入了free和len字段,带来了很多好处:获取字符串长度:SDS是O(1),C字符串是O(n)缓冲区溢出:使用C字符串的API时,如果字符串长度增加 存取二进制数据:SDS可以,C字符串不可以。 此外,由于SDS中的buf仍然使用了C字符串(即以’0’结尾),因此SDS可以使用C字符串库中的部分函数;但是需要注意的是,只有当SDS用来存储文本数据时才可以这样使用,在存储二进制数据时则不行(’0’ (3)SDS与C字符串的应用Redis在存储对象时,一律使用SDS代替C字符串。例如set hello world命令,hello和world都是以SDS的形式存储的。

    1.3K70

    Redis内存模型

    这篇文章主要介绍Redis的内存模型(以3.0为例),包括Redis占用内存的情况及如何查询、不同的对象类型在内存中的编码方式、内存分配器(jemalloc)、简单动态字符串(SDS)、RedisObject 图片来源:《Redis设计与实现》通过SDS的结构可以看出,buf数组的长度=free+len+1(其中1表示字符串结尾的空字符);所以,一个SDS结构占据的空间为:free所占长度+len所占长度+ (2)SDS与C字符串的比较SDS在C字符串的基础上加入了free和len字段,带来了很多好处:获取字符串长度:SDS是O(1),C字符串是O(n)缓冲区溢出:使用C字符串的API时,如果字符串长度增加 此外,由于SDS中的buf仍然使用了C字符串(即以’0’结尾),因此SDS可以使用C字符串库中的部分函数;但是需要注意的是,只有当SDS用来存储文本数据时才可以这样使用,在存储二进制数据时则不行(’0’ (3)SDS与C字符串的应用Redis在存储对象时,一律使用SDS代替C字符串。例如set hello world命令,hello和world都是以SDS的形式存储的。

    36740

    深度历险:Redis 内存模型详解

    这篇文章主要介绍 Redis 的内存模型(以 3.0 为例),包括 Redis 占用内存的情况及如何查询、不同的对象类型在内存中的编码方式、内存分配器(jemalloc)、简单动态字符串(SDS)、RedisObject SDS 结构SDS 的结构如下:?其中,buf 表示字节数组,用来存储字符串;len 表示 buf 已使用的长度;free 表示 buf 未使用的长度。下面是两个例子:?? SDS 与 C 字符串的比较SDS 在 C 字符串的基础上加入了 free 和 len 字段,带来了很多好处:获取字符串长度:SDS 是 O(1),C 字符串是 O(n)。 此外,由于 SDS 中的 buf 仍然使用了 C 字符串(即以’0’结尾),因此 SDS 可以使用 C 字符串库中的部分函数。 SDS 与 C 字符串的应用Redis 在存储对象时,一律使用 SDS 代替 C 字符串。例如 set hello world 命令,hello 和 world 都是以 SDS 的形式存储的。

    32720

    深入学习Redis:Redis内存模型

    这篇文章主要介绍Redis的内存模型(以3.0为例),包括Redis占用内存的情况及如何查询、不同的对象类型在内存中的编码方式、内存分配器(jemalloc)、简单动态字符串(SDS)、RedisObject (2)SDS与C字符串的比较SDS在C字符串的基础上加入了free和len字段,带来了很多好处:获取字符串长度:SDS是O(1),C字符串是O(n)缓冲区溢出:使用C字符串的API时,如果字符串长度增加 存取二进制数据:SDS可以,C字符串不可以。 此外,由于SDS中的buf仍然使用了C字符串(即以’0’结尾),因此SDS可以使用C字符串库中的部分函数;但是需要注意的是,只有当SDS用来存储文本数据时才可以这样使用,在存储二进制数据时则不行(’0’ (3)SDS与C字符串的应用Redis在存储对象时,一律使用SDS代替C字符串。例如set hello world命令,hello和world都是以SDS的形式存储的。

    29320

    Redis为什么这么快?一文深入了解Redis内存模型!

    这篇文章主要介绍 Redis 的内存模型(以 3.0 为例),包括 Redis 占用内存的情况及如何查询、不同的对象类型在内存中的编码方式、内存分配器(jemalloc)、简单动态字符串(SDS)、RedisObject SDS 结构SDS 的结构如下:?其中,buf 表示字节数组,用来存储字符串;len 表示 buf 已使用的长度;free 表示 buf 未使用的长度。下面是两个例子:?? SDS 与 C 字符串的比较SDS 在 C 字符串的基础上加入了 free 和 len 字段,带来了很多好处:获取字符串长度:SDS 是 O(1),C 字符串是 O(n)。 此外,由于 SDS 中的 buf 仍然使用了 C 字符串(即以’0’结尾),因此 SDS 可以使用 C 字符串库中的部分函数。 SDS 与 C 字符串的应用Redis 在存储对象时,一律使用 SDS 代替 C 字符串。例如 set hello world 命令,hello 和 world 都是以 SDS 的形式存储的。

    17720

    Redis 中的 “SOS”,不对,是 SDS

    01、SDS 数据结构Redis 底层是基于 C 语言来开发的,但是它没有采用 C 语言传统的字符串表示方式,而是自定义了一种叫做 SDS(Sample Dynamic String,简单动态字符串)的数据结构来表示字符串 传统的 C 语言的字符串是采用空字符(0)作为结尾的字符数组,SDS 的数据结构稍微复杂一点,整个结构包含三个部分,是 Redis 的基础。(阿粉猜测这里就是传说中的青出于蓝而胜于蓝)。 02、为什么采用 SDS2.1、SDS 与 C语言字符串的区别在说明 Redis 为什么要自定义 SDS 之前,阿粉觉得我们应该先看一下 SDS 与传统的 C 语言的字符串有什么区别,知道了具体的区别我们才能知道这样实现的原因是什么 这就带来了另一个 Redis 特性,就是二进制的安全性。 03、总结这篇文章阿粉跟大家介绍了一下 RedisSDSSDS 底层的组成结构,并且与 C 语言传统字符串进行的详细的对比,阐述了 SDS 出现解决了哪些问题,最后带大家从源码中简单的看了几个底层的函数实现

    13720

    redis 为什么把简单的字符串设计成 SDS

    面试官:了解redis的String数据结构底层实现嘛?铁子:当然知道,是基于SDS实现的面试官:redis是用C语言开发的,那为啥不直接用C的字符串,还单独设计SDS这样的结构呢? 我们知道redis是用C写的,但它却没有完全直接使用C的字符串,而是自己又重新构建了一个叫简单动态字符串SDS(simple dynamic string)的抽象类型。 redis也支持使用C语言的传统字符串,只不过会用在一些不需要对字符串修改的地方,比如静态的字符输出。而我们开发中使用redis,往往会经常性的修改字符串的值,这个时候就会用SDS来表示字符串的值了。 有一点值得注意:在redis数据库中,key-value键值对含有字符串值的,都是由SDS来实现的。比如:在redis执行一个最简单的set命令,这时redis会新建一个键值对。 在高并发场景下频繁遍历字符串,获取字符串的长度很有可能成为redis的性能瓶颈,所以SDS性能更好一些。

    18630

    redis 为什么把简单的字符串设计成 SDS

    题目大致是这样的面试官:了解redis的String数据结构底层实现嘛铁子:当然知道,是基于SDS实现的面试官:redis是用C语言开发的,那为啥不直接用C的字符串,还单独设计SDS这样的结构呢铁子:· 我们知道redis是用C写的,但它却没有完全直接使用C的字符串,而是自己又重新构建了一个叫简单动态字符串SDS(simple dynamic string)的抽象类型。 redis也支持使用C语言的传统字符串,只不过会用在一些不需要对字符串修改的地方,比如静态的字符输出。而我们开发中使用redis,往往会经常性的修改字符串的值,这个时候就会用SDS来表示字符串的值了。 有一点值得注意:在redis数据库中,key-value键值对含有字符串值的,都是由SDS来实现的。比如:在redis执行一个最简单的set命令,这时redis会新建一个键值对。 在高并发场景下频繁遍历字符串,获取字符串的长度很有可能成为redis的性能瓶颈,所以SDS性能更好一些。

    17071

    Redis】一、Redis的简单动态字符串SDS

    Redis没有直接使用C语言传统的字符串表示(以空字符 0 结尾的字符数组),而是构建了一种名为简单动态字符串SDS的抽象类型,并将SDS用作Redis的默认字符串表示。 上图中是一个 SDS对象, 字符串的值是 Redis; 长度为5,剩余可用空间为3 ; ‘0’ 是SDS遵循了C字符串以空字符串结尾的惯例(之所以遵循是因为可以让SDS重用C语言的一些库函数 ), 保存这个空字符串的一个字节空间不计算在 对比两个结构,我们来分析一下 为何 Redis要自己定义SDS1. SDS就不存在这样的问题,Redis的buf数组是用来保存一系列的二进制数据。总结----1.Redis 什么时候用C语言字符串? redis里面,C字符串只会作为字符串字面量用在一些无须对字符串值进行修改的地方,例如打印日志;2.SDS与C字符串的区别①.

    12040

    相关产品

    • 云数据库 Redis

      云数据库 Redis

      云数据库 Redis,数据库缓存,数据库存储,云数据库 云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。 云数据库Redis是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。

    相关资讯

    热门标签

    扫码关注云+社区

    领取腾讯云代金券