sds(simple dynamic string) 简单动态字符串,是redis内部存储字符串类型的数据结构,是对原生c语言中char[]的扩展和封装. sdshdr数据结构(v3.0及以前) sds...是如何使用的. set命令 在执行set key redis命令时,sds存储字符串的过程 1....惰性删除,预分配空间不会被释放,除非该字符串所对应的键被删除,或者redis启动时重新载入的字符串不会预分配空间. 3. 二进制安全,sds能存储任意二进制数据,而不仅仅是可打印字符. 4....与传统的c语言字符串类型兼容. sds的缺点及优化 缺点: 1. redis的key也使用sds作为存储数据结构,但key是不会有更改操作的,这就造成了空间的浪费. 2. sds中的len,free的类型是...优化: 针对这些缺点redis在v3.2之后,对数据格式做了调整优化. 1.
Redis面试中经常被问到,Redis效率为什么这么快,很多同学往往回答:① Redis基于内存操作;② Redis是单线程的,采用了IO多路复用技术;③ Redis未使用C语言字符串,使用了SDS字符串...C语言字符串使用长度为n+1的字符数组来表示长度为n的字符串,并且字符数组的最后一个元素总是空字符'\0',因为这种字符串表示方式不能满足Redis对字符串在安全性、效率以及功能方面的要求,所以Redis...在Redis中,包含字符串值的键值对都是使用SDS实现的,除此之外,SDS还被用于AOF缓冲区、客户端状态的输入缓冲区。...相比较而言,Redis程序只要访问SDS的len属性就可以直接获取到字符串长度,时间复杂度为O(1),确保获取字符串长度不会成为Redis性能瓶颈,比如对字符串键反复执行strlen命令。...通过空间预分配,Redis可以减少连续执行字符串增长操作所需的内存重分配次数,通过惰性空间释放,SDS避免了缩短字符串时所需的内存重分配操作,并为将来由可能的增长操作提供了优化。
1:SDS介绍 我们在redis中执行命令 set key name 的时候,key和name都是字符串类型,而且字符串(string)在redis中是会经常用到的类型,那redis是如何保存字符串的呢...我们接下来往下看 众所周知,redis是c写的,在c中使用char来保存字符串,并且用\0作为字符串的结尾,但是redis不是这样保存的,redis是使用一种叫SDS的结构来保存字符串的。...结构如下(redis3.2以前) struct sdshdr{ int len; int free; char buf[]; } 那么问题来了,redis为什么 会用SDS的结构...1) 2:保证二进制的安全 因为SDS并不是以\0为结尾的标志,自然就保证了二进制的安全 3:内存管理策略(预分配内存和惰性空间释放策略) redis是一个高速的缓存数据库,需要频繁的对字符串进行操作,..._32; return SDS_TYPE_64; #else return SDS_TYPE_32; #endif }
[Redis 源码解析 1:字符串 SDS ] Redis 中字符串都用自定义的结构**简单动态字符串(Simple Dynamic Strings,SDS),而不是C语言的字符串。...Redis 中使用到的字符串都是用 SDS,例如 key、string 类型的值、sorted set 的 member、hash 的 field 等等等等 数据结构 旧版本的结构 在 3.2 版本之前...我们来看一下新版本的 SDS 结构。...在 Redis 3.2 版本之后,Redis 将 SDS 划分为 5 种类型: 类型 字节 位 sdshdr5 < 1 <8 sdshdr8 1 8 sdshdr16 2 16 sdshdr32 4 32...的初始化 SDS的初始化如下,开始创建时SDS分配的buf空间大小与字符串长度一致 /* Create a new sds string starting from a null terminated
源代码 sds sdscat(sds s ,const char *t) { return sdscatlen(s,t,strlen(t)); } sds sdscatsds(sds s,const...sds t) { return sdscatlen(s,t,sdslen(t)); } 说明 这两个函数的功能几乎是一样的:把字符串t添加到字符串s的后面,并且长度为t的长度。...疑惑 但是为什么要把char *和sds字符串区别开来呢?sds的定义就是插入类型的指针。这样做的目的是什么呢?是出于什么考虑呢?
01 前言 从今天开始我们就要学习redis的源码了,想想还有点小激动呢。 前方高能预警,非战斗人员迅速撤离。...又一个但是来了,redis底层是用C语言写的,如果对C语言一窍不通,那还是算了,前方等待的是一座大山。墙裂推荐去了解一下C.emmmm,幸好我会C,哈哈哈,毕竟他是开启偶代码之路的小哥哥。...02 介绍 Redis没有直接使用C语言传统的字符串来表示(以空字符串结尾的字符数组),而是自己构造了一种名为简单动态字符串SDS。 之前看的String类型的数据结构底层就是用SDS实现的。...char buf[]; //初始化sds分配的数据空间 }; 举个栗子: 我们之前设置一个名为str1的字符串,值为redis,其实他在内存上的结构大致如下: ?...buf为char[]的数组,分配了(len+1+free)个字节的长度,前len个字节保存redis这5个字符串,接下来1个字节保存了'\0',剩下的free个字节未使用。
sds 在redis中,存储字符串的结构称为 sds (Simple Dynamic String) 简单动态字符串 在源码sds.h中定义如下: typedef char *sds; /* Note...存储结构 在sds中,8的存储结构如下: typedef char *sds; struct __attribute__ ((__packed__)) sdshdr8 { uint8_t len...); } break; case SDS_TYPE_8: SDS_HDR(8,s)->len = newlen;...; case SDS_TYPE_32: SDS_HDR(32,s)->len = newlen; break; case...,sds的指针位置-结构体长度=sdshdr的指针位置: #define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)
源程序 sds sdscatlen(sds s, const void *t, size_t len) { struct sdshdr *sh; size_t curlen = sdslen(s);...说明 Append the specified binary-safe string pointed by 't' of 'len' bytes to the end of the specified sds...该函数的功能就是在原sds字符串的基础上添加len长度的字符串。新添加的字符串的头指针是t,添加到s的位置。
源代码 sds sdsnewlen(const void *init, size_t initlen) { >struct sdshdr *sh; >if (init) { > sh = zmalloc...修改后的sdsnewlen() sds mysdsnewlen(const void *init,size_t initlen) { struct sdshdr *sh; >if(init) { >
源程序 void sdsIncrLen(sds s,int incr) { struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));...unsigned int)(-incr)); sh->len += incr; sh->free -= incr; s[sh->len] = '\0'; } 这个函数用来计算调整sds...每次对sds字符串经过操作之后,字符串的len和free的大小都会变动。
redis学习 - sds字符串 Redis 设计与实现:如果想要知道redis底层,这本书可以给予不少的帮助,非常推荐每一位学习redis的同学去翻一翻。...redis的sds是如何实现的 由于c语言的string是以\0结尾的Redis单独封装了SDS简单动态字符串结构,如果在字符串变量十分多的情况下,会浪费十分多的内存空间,同时为了减少malloc操作,...redis封装了自己的sds字符串。...://zhangtielei.com/posts/blog-redis-sds.html 解析redis的字符串sds数据结构: https://blog.csdn.net/wuxing26jiayou...Redis源码剖析--动态字符串SDS https://zhuanlan.zhihu.com/p/24202316 C基础 带你手写 redis sds https://www.lagou.com/lgeduarticle
前言 本系列文章从源码角度分析redis的设计与实现,分析的源码为最新版本7.2.4。下载地址(https://github.com/redis/redis/tree/7.2.4)。...SDS是简单动态字符串的缩写(simple dynamic strings),是redis中最基本的一种数据结构,用于存储字符串和整数类型。...所以redis中为SDS定义了5种结构,根据字符串长度选择合适类型。 如何区分类型? SDS结构引入多种类型后产生了一个问题,如何判断sds到底是哪种类型呢?...这不符合redis中可以保存任意二进制数据的需求。...对于一个把内存和cpu用到极致的人,redis作者为啥要把sds设计成非内存对齐呢。
源程序 //将sds字符串置空 void sdsclear(sds s) { struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr...->free += sh->len; sh->len = 0; sh->buf[0]='\0'; } 这个函数挺简单的,没有什么特别之处,功能就是将原来的sds
源函数 static inline size_t sdslen(const sds s) { struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr...))); return sh->len; } 这是redis中用来计算字符串长度的函数,时间复杂度为O(1)。...源函数 static inline size_t sdslen(const sds s) { struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)))...; >return sh->free; } 这是描述当前sds字符串中还剩下的空间量的函数。
源程序 sds sdsMakeRoomFor(sds s,size_t addlen) { struct sdshdr *sh,*newsh; sizt_t free = sdsavail...sdslen(s); sh = (void*)(s-(sizeof(struct sdshdr))); newlen = (len+addlen); if(newlen < SDS_MAX_PREALLOC...) newlen *= 2; else newlen += SDS_MAX_PREALLOC; newsh = realloc(sh,sizeof(struct...if(newsh == NULL) return NULL; newsh->free = newlen - len; return newsh->buf; } 这个函数是用来为sds...仅仅增加free的长度,不会改变sds字符串的长度。 这个函数比较难理解的地方是:扩容的幅度这里,为什么扩新长度的2倍
源程序 size_t sdsAllocSize(sds s) { struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr))); return...sizeof(*sh)+sh->len+sh->free+1; } 用来计算sds字符串总共的长度大小,包括为sds存储字符提供的大小,还有free的大小,还有字符串末尾的'\0'。
redis使用sds(simple dynamic string)实现了字符串的存储。sds实际上就是TLV格式的数据结构。...不同的首部可以表示不同长度的字符串数据,如SDS_TYPE_8最大可以表示(2^8 -1)大小的字符串数据。划分为不同类型的sds首部是为了减少内存浪费。...sds实现了字符串存储的扩展(基于realloc命令)和收缩(使用malloc重新申请复制数据)以及字符串的一般操作,如大小写转换,截取,拼接等。在使用sds时要注意内存变动可能导致的性能问题。...image.png 源代码解析参见:sds.c和sds.h
源程序 sds sdsRemoveFreeSpace(sds s) { struct sdshdr *sh; sh = (void*)(s-(sizeof(struct sdshdr)));...// sh->free; return sh->buf; } 删掉sds字符串中的空白部分,即将free的大小置为0. 将字符串中的空白部分删除这么写,是为了什么呢?
redis使用sds(simple dynamic string)实现了字符串的存储。sds实际上就是TLV格式的数据结构。...不同的首部可以表示不同长度的字符串数据,如SDS_TYPE_8最大可以表示(28 -1)大小的字符串数据。划分为不同类型的sds首部是为了减少内存浪费。...sds实现了字符串存储的扩展(基于realloc命令)和收缩(使用malloc重新申请复制数据)以及字符串的一般操作,如大小写转换,截取,拼接等。在使用sds时要注意内存变动可能导致的性能问题。...源代码解析参见:sds.c和sds.h
源代码 sds sdscpylen(sds s, const char *t, size_t len) { struct sdshdr *sh = (void*) (s-(sizeof(struct...len] = '\0'; sh->len = len; sh->free = totlen-len; return s; } 说明 将t指向的字符串复制到字符串s中,其中s字符串是sds...源代码 sds sdscpy(sds s, const char *t) { return sdscpylen(s, t, strlen(t)); } 说明 功能和sdscpylen()一样,但不同的是
领取专属 10元无门槛券
手把手带您无忧上云