redis源码分析(五):数据持久化

redis 是基于内存读写的数据库,所有数据都存储在内存中,所以存储的数据大小受到了限制。但redis依然提供了固化功能,与mysql,leveldb等数据库不同的是,redis的存储功能只是用做备份,恢复的功能,全量数据还是存储在内存中。
redis内部提供了两种固化数据的方式,aof 和rdb。

1.aof

数据写入

aof全称appendOnlyFile,要让redis支持aof方式,需要将配置文件的appendonly配置为"yes",并配置appendfsync 为everysec/always/no。everysec是redis推荐的配置,我们默认以这种方式来具体分析。
每次对数据有修改的操作,均会以append的方式写入server.aof_buf中,每秒钟将在时间事件中检查这个缓冲区是否为空,不空则说明有新的更新,将其写入aof文件中(注意write函数并非实时写入硬盘,可以用flush函数来强制刷新未写入的缓存),并触发刷新任务,通知bio模块创建的线程中执行。aof的文件是相对"白话"的,如图是我本地截取的aof文件:

1.png

'*'后跟的是当前的参数个数,'$'后跟的是下一个参数的长度,再后来就是参数了。一个redis中有多个数据库,我们需要确定数据增改到那个数据库了,因此第一句为select db的操作。

除了手动配置的刷新aof规则外,客户端可以手动触发bgrewriteaof来覆盖已有的aof文件(未开启aof配置也是支持这个命令),客户端发起此命令后,redis会fork一个子进程来将内存中的数据保存到文件中。那么问题来了,子进程运行过程中,redis主进程依然在提供服务,如果期间写入新的数据,那么主子进程间的数据将会不同步,如何解决?期间的数据会存储在链表数据块server.aof_rewrite_buf_blocks中,当主进程用wait方法检测到子进程退出以后,会调用backgroundRewriteDoneHandler函数,将缓存的数据附加到新的aof文件中。重写aof可以减小aof文件的大小,因为部分数据失效,或者来回更改,在everysec的配置中均会保存下来,但是重写aof之后,无效数据,或者中间状态的修改均会被忽略。

数据载入

redis刚启动的时候会优先检查是否开启aof配置(否则rdb),如果是则加载aof配置文件,每个参数均以'\n'结尾,因此读取/判断合法十分方便。创建一个fakeClient来模拟客户端将数据插入内存中。这里有一个疑问,数据载入的同时,服务依然处理客户端的io任务,这样不怕aof的旧文件写脏用户新插入的数据么

2.rdb

数据写入

用户可以配置redis中save的参数,格式为save sec commit 代表每sec秒,如果有commit次修改,则由服务自身执行一次bgsave操作。save配置可以有多个,相互之间是或的关系。server.dirty用来记录数据修改次数,bgsave完成以后,会将其置0。
redis的每次写入都是全量操作,步骤如下

  • 1.创建临时文件,写入redis字符串+版本号。

  • 2.写入select db语句,如果当次db没有数据,跳到下一个,没有更多数据库了,跳到步骤5。

  • 3.创建字典的迭代器,循环字典内的元素。

  • 4.redis都是键值对数据,分别写入超时时间(如果有的话),value的类型,key,value,其中key和value尽可能的压缩编码。如果迭代器到达结尾,跳到步骤2。

  • 5.大于4的版本加入了校验码,校验和使用crc计算,用临时文件覆盖正式rdb文件,流程结束。

数据载入

这个也没有悬念了,怎么写入,就怎么加载;读取到数据之后直接调用dbAdd函数把数据插入到字典server.db[dbnum]->dict中。

对比下aof和rdb。

1.aof文件相对于直接保存了语句和中间过程。所以更易于开发者修改查看数据。追加修改的命令,对io,cpu,内存压力均较小,相对来说更吃存储空间。
2.aof的缺点就是rdb的优点了。特别是如果rdb的save参数保存不当,redis会频繁执行bgsave命令,每次都是全量修改,在数据量大,修改频繁的时候会是个灾难。

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

推荐阅读更多精彩内容

  • 从这篇文章开始,将依次介绍Redis高可用相关的知识——持久化、复制(及读写分离)、哨兵、以及集群。 本文将先说明...
    不变甄心阅读 692评论 0 4
  • 前言 在上一篇文章中,介绍了Redis内存模型,从这篇文章开始,将依次介绍Redis高可用相关的知识——持久化、复...
    Java架构阅读 2,296评论 3 21
  • 企业级redis集群架构的特点 海量数据 高并发 高可用 要达到高可用,持久化是不可减少的,持久化主要是做灾难恢复...
    lucode阅读 2,193评论 0 7
  • 周五的晚上和同事漫步在繁华的衡山路上,排排坐的酒吧里喧闹的DJ撩拨着都市男女脆弱而又敏感的神经,但热闹是他们的,我...
    意语轩阅读 981评论 8 2
  • 红衰绿减小院幽,落尽繁华青红褪。 ——读友的诗《烟花故里路,何年与君逢》有感 红与绿终会被荒凉和干枯所代替, 春,...
    Angel李子汐阅读 840评论 8 32