【Redis设计和实现】一:redis高性能SDS字符串实现分析

字符串在C语言中的存储方式


在C语言中,采用长度为N+1的字符数组来存储一个长度为N的字符串,最后一个字符是空字符\0,表示字符串的结尾。

在C语言中,增加或者减少字符串的长度都涉及内存空间的重新分配,这是很耗时的,对于一个作为数据库的应用redis来说,直接使用这种方式会严重影响性能。C语言对字符串的操作过程如下:

  1. 如果增加字符串的长度的话,在操作之前需要通过重新分配内存来扩展存储该字符串底层数组的长度,否则会发生缓冲区溢出。
  2. 如果减少字符串长度的话,在操作之前同样需要重新分配内存释放多余的内存空间,不重新分配内存虽然不会直接造成程序崩溃,但是当这种操作多了以后,就会有大量的空闲的内存空间而导致内存泄漏问题。

Redis字符串存储方案


SDS存储的结构体

struct sdshdr{
        int len;            //buf数组中已经使用的字节的数量,也就是SDS字符串长度
        int  free;          //buf数组中未使用的字节的数量
        char buf[];      //字节数组,字符串就保存在这里面
};

redis通过定义结构体的方式,扩展了C语言底层字符串的缺点,字符串长度的获取时间复杂度从原来的O(N)变成了O(1),另一方面也可以通过free的动态改变减少内存的分配。需要强调一点的是buf数组不是存储的字符,而是二进制数组,因为C语言字符串中间是不能出现空字符的,而二进制数据中间很有可能会有空字符,所以C语言是二进制不安全的,而redis又是二进制安全,为了存储多种类型的数据,redis就直接把所有数据当作二进制来存储,这样就可以存储媒体文件和字符串,所以SDS虽然叫简单动态字符串,但是它可不只是用来保存字符串哦

buf数组动态分配策略

既然redis定义了一个结构体来描述一个SDS字符串,多出来的几个变量肯定是有很大作用的,其中一个很重要的作用就是实现对字符串的灵活操作并且尽量减少内存重新分配和回收操作。

redis的内存分配策略如下:

  1. 当SDS的len属性长度小于1MB时,redis会分配和len相同长度的free空间。至于为什么这样分配呢,我觉得这个有点像一种惯性预测。举个例子,比如一个乞丐向你要10块钱,如果让你预测下一个乞丐会让你要多少,这个时候我没有其他的依据,当然就只能根据上一个乞丐的行为来推测下一个乞丐会让我要10块啦~放到redis里面,上次用了len长度的空间,那么下次程序可能也会用len长度的空间,所以redis就为你预分配这么多的空间。
  2. 但是当SDS的len属性长度大于1MB时,这个时候我在根据这种惯性预测来分配的话就有点得不偿失了,比如修改后的SDS长度为100MB,那我也傻乎乎的给你分配100MB空闲内存等你用么?万一你下次用不了这么多了,对于内存而言就亏大发了。所以,redis是将1MB设为一个风险值,没过风险值你用多少我就给你多少,过了的话那这个风险值就是我能给你临界值,感觉父母给零花钱也是酱紫。。至于为什么是1MB,这个问题就和redis使用的场景有关了。

reids的内存回收策略如下:

  1. redis的内存回收采用惰性回收,即你把字符串变短了,那么多余的内存空间我先不还给操作系统,先留着,万一马上又要被使用呢。短暂的持有资源,既可以充分利用资源,也可以不浪费资源。这是一种很优秀的思想。

综上所述,redis实现的高性能字符串的结果就把N次字符串操作必会发生N次内存重新分配变为人品最差时最多发生N次重新分配。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容