1.标准strcat 会有溢出风险,sdscat无溢出风险 2.空间预分配,惰性空间释放 空间预分配:sds分配空间时,如果原来是5,free是0, sdscat追加一个10长度的,此时字符串加长到15,free也同时分配15,总长为15 + 15free + 1(/0) 为31字节: 若大于1M后则以1M为单位追加. 这么做的原因是,内存分配是比较耗时的操作[https://baike.baidu.com/item/realloc/659993?fr=aladdin],在原地址空间后面若无足够…
0. 前言 这里对Redis底层字符串的实现分析,但是看完其实现还没有完整的一个概念,即不太清楚作者为什么要这样子设计,只能窥知一点,需要看完redis如何使用再回头来体会,有不足之处还望告知. 涉及文件:sds.h/sds.c 1.  数据结构: typedef char *sds; struct sdshdr { unsigned int len; //buf中已使用的字节数 unsigned int free; //buf中未使用的字节数 char buf[]; //缓冲区 }; 这里向外…
初衷 从开始工作就开始使用Redis,也有一段时间了,但都只是停留在使用阶段,没有往更深的角度探索,每次想读源码都止步在阅读书籍上,因为看完书很快又忘了,这次逼自己先读代码.因为个人觉得写作需要阅读文字来增强灵感,那么写代码的,就阅读更多代码来增强灵感吧. redis的实现原理,在<Redis设计与实现>一书中讲得很详细了,但是想通过结合代码的形式再深入探索,加深自己的理解,现在将自己探索的心得写在这儿. sds结构体的定义 #define SDS_TYPE_5 0 #define SDS_T…
redis使用sds代替char *字符串, 其定义如下: typedef char *sds; struct sdshdr { unsigned int len; unsigned int free; char buf[]; }; sds指向了char 字符串 sdshdr是字符串头 结构比较巧妙 使用char buf[]存放字符串实际内容 注意char *buf和char buf[]是不同的 sizeof(sdshdr)等于8,而不是我以为的12 连续内存结构如下: 0----7 sdshd…
C 语言的字符串函数 C 语言 string 函数,在 C 语言中可以使用 char* 字符数组实现字符串,C 语言标准库 string.h 中也定义了多种字符串操作函数. 字符串使用广泛,需要满足: 高效的字符串操作,比如追加.拷贝.比较.获取长度 能保存任意的二进制数据,比如图片 尽可能省内存 为什么 Redis 不直接使用 C 语言的字符串? C 语言 char* 以 '\0'标识字符串的结束,则中间含有'\0'的字符串无法被正确表示:也正因为此,没有办法保存图像等二进制数据. C 语言…
本文为读<Redis设计与实现>的记录.该书以Redis2.9讲解Redis相关内容.请注意版本差异. Redis使用C语言实现,他对C语言中的char类型数据进行封装,构建了一种简单动态字符串(以下简称SDS),该字符串的结构如下 struct sdshdr{ //记录buf数组中已使用字节的数量 //获取字符串的长度时,就是直接返回的这个字段的值 int len; //记录buf数组中未使用字节的数量 int free; //字节数组,用于保存字符串 char buf[]; } SDS遵循…
sds模块的具体实现: 1.sdsnewlen 根据参数生成一个sds字符串 sds sdsnewlen(const void *init, size_t initlen) { struct sdshdr *sh; //如果初始化的内容为NULL,则生成一个内容只有一个\0的串,但是长度不会变,还是传入的长度.zmalloc和zcalloc的功能一样,这个地方为啥还要调用不同的呢. if (init) { sh = zmalloc(); } else { sh = zcalloc(); } if…
Redis开发者在开发过程中没有使用系统的原始字符串,而是使用了自定义的sds字符串,这个模块的编写是在文件:sds.h和sds.c文件中.Redis自定义的这个字符串好像也不是很复杂,远不像nginx自定义的一样复杂,但也存在一些问题. 在.h文件中定义了一个新的类型和一个结构体分别是: typedef char *sds;//定义了sds的字符串类型,使用的仍是字符串指针,只是多了个头部,具体定义见sdshdr. //动态字符串,数组的长度是可变的. struct sdshdr { unsi…
Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话,是远远不足以应对面试提问的.本文简单介绍了Redis底层最重要的数据结构 - 简单动态字符串(SDS) Redis使用C语言开发,但并没有使用C语言传统的字符串表示(以空字符结尾的字节数组,以下简称C字符串),而是自己构建了一种名为简单动态字符串的(simple dynamic string,SDS…
一.  SDS概述 Redis 没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型,并将SDS用作Redis的默认字符串表示.Redis只会使用C字符串作为字面量.在Redis里,使用SDS来表示字符串值,是一个可以被修改的字符串,字符串“键值对”底层都是由SDS实现的. -- 例1:客户端执行如下命令: > set msg "hello world" OK > get msg &quo…
图解Redis之数据结构篇--简单动态字符串SDS 前言     相信用过Redis的人都知道,Redis提供了一个逻辑上的对象系统构建了一个键值对数据库以供客户端用户使用.这个对象系统包括字符串对象,哈希对象,列表对象,集合对象,有序集合对象等.但是Redis面向内存并没有直接使用这些对象.而是使用了简单动态字符串,链表,字典(散列表),跳跃表,整数集合,压缩列表这些数据结构来操作内存. 系列文章 图解Redis之数据结构篇--简单动态字符串SDS 图解Redis之数据结构篇--链表 图解Re…
一,什么是SDS? 1.引出SDSC字符串:c语言中,用空字符结尾的字符数组表示字符串简单动态字符串(SDS):Redis中,用SDS来表示字符串.在Redis中,包含字符串值的键值对在底层都是由SDS实现的首先,Redis使用C语言写的,但是Redis没有使用C语言传统的字符串表示,它自己构建了简单字符串的抽象类型来表示字符串. 2.SDS的定义一个sdshdr结构表示一个SDS值.结构如下:struct sdshdr {    //记录buf数组中已使用字节的数量    int len;  …
1.SDS 定义 在C语言中,字符串是以’\0’字符结尾(NULL结束符)的字符数组来存储的,通常表达为字符指针的形式(char *).它不允许字节0出现在字符串中间,因此,它不能用来存储任意的二进制数据. sds的类型定义 typedef char *sds; 肯定有人感到困惑了,竟然sds就等同于char *? sds和传统的C语言字符串保持类型兼容,因此它们的类型定义是一样的,都是char *,在有些情况下,需要传入一个C语言字符串的地方,也确实可以传入一个sds. 但是sds和char…
一,简单的动态字符串 1,Redis自己构建了一种名为简单动态字符串的抽象类型,并将SDS用作Redis的默认字符串表示, 2,在redis的数据库里面,包含字符串值的键值对在底层都是由SDS实现的 举个栗子:set msg "hello word" (1)键值对的键是一个字符串对象,对象的底层是一个保存字符串msg的SDS (2)键值对的值也是一个字符串对象,对象的底层是个保存字符串"hello word"的SDS 3,SDS的定义 (1) SDS遵循C字符串以空…
几个概念1:key对象 数据库存储键值对的键,总是一个字符串对象.2:value对象 数据库存储键值对的值,可以是字符串对象,list对象,hash对象,set对象,sorted set对象.     例如:            set msg "hello world" 则redis在数据库中创建一个新的键值对,键和值都是一个字符串对象,底层实现都是一个sds对象.            rpush fruits "apple" "banana&quo…
本文作者: Pushy 本文链接: http://pushy.site/2019/12/21/redis-sds/ 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议.转载请注明出处! 1. 什么是 SDS 众所周知,在 Redis 的五种数据解构中,最简单的就是字符串: redis> set msg "Hello World" 而 Redis 并没有直接使用 C 语言传统的字符串表示,而是自己构建了一个名为简单动态字符串(Simple dy…
C语言中,传统的字符串表示是以空字符结尾的字符数组,Redis的字符串没有直接使用该表示,而是选择构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型. 在Redis中,C字符串只会作为字符串字面量(string literal)用在一些无需对字符串值进行修改的地方,例如打印日志等场景. 结构 struct SDS<T> { T capacity; // 数组容量 T len; // 数组长度 bytes flags: // 特殊标识位 bytes[]…
Redis没有直接使用C字符串(以'\0'结尾的字符数组),而是构建了一种名为简单动态字符串( simple  dynamic  string, SDS)的抽象类型,并将SDS用作Redis的默认字符串表示.在Redis里面,C字符串只会作常量值,比如打印日志: redisLog(REDIS_WARNING,"Fatal: Can't initialize Background Jobs."); 当Redis需要一个可被修改的字符串时,就会使用SDS来表示字符串值,在Redis中,包含…
redis中动态字符串sds相关的文件为:sds.h与sds.c 一.数据结构 redis中定义了自己的数据类型"sds",用于描述 char*,与一些数据结构 typedef char *sds; /* Note: sdshdr5 is never used, we just access the flags byte directly. * However is here to document the layout of type 5 SDS strings. */ struct…
目录 redis源码分析系列文章 前言 API使用 embstr和raw的区别 SDSHdr的定义 SDS具体逻辑图 SDS的优势 更快速的获取字符串长度 数据安全,不会截断 SDS关键代码分析 获取常见值(抽象出常见方法) 创建对象 删除 添加字符(扩容)重点!!! 总结 参考资料 redis源码分析系列文章 [Redis源码系列]在Liunx安装和常见API 为什么要从Redis源码分析 前言 上篇我们已经了解了Redis是什么,在Linux上如何安装,常见的数据类型和API使用,如果有不明…
源码阅读基于Redis4.0.9 SDS介绍 redis 127.0.0.1:6379> SET dbname redis OK redis 127.0.0.1:6379> GET dbname "redis" 从上面的例子可以看到,key为dbname的值是一个字符串"redis" Redis源码是用c写成,但并没有使用c的字符串.c的字符串有以下缺点: 没有储存字符串长度的变量,获取长度只能靠遍历字符串 扩容麻烦.没有相应保护,容易造成缓冲区溢出 更…
2021开工第一天,就有小伙伴私信我,还给我分享了一道他面阿里的redis题(这家伙绝比已经拿到年终奖了),我看了以后觉得挺有意思,题目很简单,是那种典型的似懂非懂,常常容易被大家忽略的问题.这里整理出来分享一下,顺便自己巩固一下基础,希望对正在面试和想要面试的兄弟有点帮助. 题目大致是这样的 面试官:了解redis的String数据结构底层实现嘛? 铁子:当然知道,是基于SDS实现的 面试官:redis是用C语言开发的,那为啥不直接用C的字符串,还单独设计SDS这样的结构呢? 铁子:·····…
声明:这是本人参考黄建宏的<redis设计与实现>(源码版本是redis3.0)来学习redis3.20源码的笔记,如果有什么不对的地方,欢迎大家指正,大家一起学习.一起进步,QQ:499656254. 一.SDS介绍 SDS又叫简单动态字符串,在Redis中默认使用SDS来表示字符串.比如在Redis中的键值对中的键一般都是使用SDS来实现.首先需要说明的是在Redis中,字符串不是用传统的字符串来实现,而是Redis自己构建了一个结构来表示字符串.优点如下: 1.O(1)时间内获取字符串长…
Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串), 而是自己构建了一种名为简单动态字符串(simple dynamic string,sds)的抽象类型, 并将sds用作 Redis 的默认字符串表示. sds简单动态字符串数据结构如下: typedef char *sds; struct sdshdr { int len; int free; char buf[]; }; len记录字符串的长度,free记录sds还剩余的空间,buf指向存储字…
redis虽说是用C语言开发的,但是redis考虑了性能.安全性.效率性.功能等要,redis底层存储字符串实现,自己实现了名为简单动态字符串(Simple dynamic string)简称SDS的结构来存储字符串,这个结构有int len(当前字符串长度), int free(未使用的字符串长度可以说是缓冲), char buf[](存储的字符串数组)这几个变量. 接下来我们开始分析C语言默认字符串和SDS字符串的区别以及redis为什么要使用SDS. 1.C语言的字符串存储并不能记录自身字…
redis的内部数据结构主要有:字符串,双端链表,字典,跳跃表. 这里主要记录redise字符串的设计.相关的源码位于:src/sds.h 和 src/sds.c.   一 字符串 sds的结构体 struct sdshdr { int len; // buf 已占用长度 int free; // buf 剩余可用长度 char buf[]; // 实际保存字符串数据的地方 }; 从这个结构可以看出,redis字符串和C的不一样,本质字符串是保存在内存的某一个位置,然后把它的指针放到buf上..…
redis 字符串 概述 redis 没有使用 c 语言风格的字符串表示(以 "\0" 作为结尾), 而是使用自定义的 sds 结构 字符串结构 定义位置 (src/sds.h) // 类型别名, 用于指向 sdshdr 的 buf 属性 typedef char *sds; // 字符串对象的结构 struct sdshdr { // 字符串长度 int len; // 字符串剩余可用空间的长度 (不包括 "\0") int free; /* * 数据空间 * s…
sds定义 struct sdshdr{ int len int free char buf[] } sds和c语言类似,仍然把字符串的末尾加上一个'.0',但是不会计入总长度,也就是不会对len造成影响,属于默认的,对使用者来说是透明的 根据这个数据的定义,我们可以判断出sds和c字符串的区别 (1)获取len长度的时间复杂度不一样,一个是O(N),一个是O(1), (2)杜绝缓冲区的溢出:对于c字符串,由于不会记录长度,所有可以造成溢出,比如我们说的strcat之类的,必须事先由使用者mal…
一.概述 在前面章节中,主要了解了 Redis用到的主要数据结构,包括:简单动态字符串.链表(双端链表).字典.跳跃表. 整数集合.压缩列表(后面再了解).Redis没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建一个对象系统,这个系统对象包括:字符串对象.列表对象.哈希对象(散列).集合对象.有序集合对象这五种类型,每种类型对象都用到了至少一种前面所介绍的数据结构. 通过这五种不同类型的对象,可以针对不同的使用场景, 在Redis 内部会为对象设置不同的数据结构实现,从而优…
本文及后续文章,Redis版本均是v3.2.8 本篇文章讲解sds基本操作函数,我们从源码角度来进一步理解. 一.sds创建函数和销毁 sds创建函数 /* Create a new sds string with the content specified by the 'init' pointer * and 'initlen'. * If NULL is used for 'init' the string is initialized with zero bytes. * * The s…