redis我与SDS的初见

一 前言

本篇文章是初步认识redis的字符串数据结构SDS(Simple Dynamic String), 其意指简单的动态字符串,字面上的含义就是smiple 代指简单,操做简单,使用者可以快点理解上手,无需关心redis内部实现;Dynamic 指动态扩展,表是可以自动的对内存空间进行动态分配;String 表示字符串,不难理解;git

公众号:知识追寻者github

知识追寻者(Inheriting the spirit of open source, Spreading technology knowledge;)redis

二 SDS结构

2.1 redis SDS数据结构

redis3.2以前数据结构以下;算法

struct sdshdr {
    unsigned int len;   
    unsigned int free;  
    char buf[];         
};
  • len 表示 buf(缓冲区)中已经使用的空间长度;
  • free 表示 buf中未使用的长度;
  • buf[] 表示缓冲区数组,存储字符;

2.12 redis 缓冲区结构

更加的形象的一个存储图像以下 buf 中的实际大小为 11(len + free + 1),其中已经使用空间 len = 5 , 未使用空间 free=5; 保留位空字符 \0 占一位;当咱们在redis储存进一个字符串zxzxz 的时候 就已经给咱们分配好了内存空间,以及后面能用使用的内存空间;若是是c 语言那么要获得一个 zxzxz 字符长度就须要遍历整个字符数组 遇到 \0 (C语言以\0区份内存空间中的字符串)后结束,才计算出一个字符串的长度,然而redis只须要一个sdslen(非c语言读者没必要纠结此类API) 就能够计算得出字符串长度; 从算法角度来看 redis 的一次获取字符串长度 为 O(1), c 语言 为 O(N), 因此redis 快不少;数组

2.2 redis 空间分配策略

其次经过上图能够发现 储存一个字符串 zxzxz , 其所占长度为5 , 为使用空间为5,\0 占1 ;缘由是 redis字符串 储存大小小于1MB 的时候 , 存储任意的字符串, 其 free大小永远与 自身的大小相同;当字符串 大小大于1MB时,其就分配free大小固定为1MB, 此称为空间预分配策略; 若是是c语言 则须要 计算当前字符串在buf中的长度,再计算即将追加的字符串长度,而后分配空间大小;故redis 的速度是至关快,相比于c 操做内存空间;数据结构

c 语言 在操做内存空间的时候要不断的计算大小,在追加字符串的时候分配空间大小,若是未进行分配,那么追加的字符串有可能覆盖已经 已经储存到 内存空间的字符串; 好比 内存空间 储存 zzz \0kkk\0; 储存 zzz 的时候所占用3 个位,加一个未分配空间1位,若是向zzz字符串进行追加一个ggg, 那么在未进行计算分配空间的状况下 原有的数据会变成 zzzggg\0k\0, 很直观的发现 内存溢出, 第一个字符串就覆盖至第二个字符串的部份内容;post

因此 redis 的操做内容空间是杜绝内存溢出,而且可以储存图片,视频等二进制数据,若是是c语言操做储存,二进制文件中一个\0就可能致使内存泄漏,缓冲区溢出等,故c语言通常只操做文本文件;spa

三 相关连接

若是想要深刻redis之SDS源码,能够参考以下连接;.net

http://www.javashuo.com/article/p-gnnttsnb-bz.htmlcode

https://juejin.im/post/5cdbafedf265da037c7d090f

https://blog.csdn.net/qq193423571/article/details/81637075

https://lynnapan.github.io/2017/07/14/redis_sds/

相关文章
相关标签/搜索