redis-持久化

redis为何需要持久化


redis是一个键值对的内存数据库,它将数据及状态保存在内存中,保证了对数据的最快访问速度,但是存在一个问题:当redis服务重启之后,所有数据及状态将全部丢失,所以:为了保证数据在奔溃重启后不丢失,redis需要实现自己的持久化机制,将内存数据存储到磁盘中

redis的持久化机制

redis为数据持久化提供了两种方案:RDB,AOF


redis的RDB持久化机制

RDB持久化功能是将redis内存中的键值对数据保存到一个经过压缩的二进制RDB文件中,通过这个RDB文件可以逆向还原redis服务器生成RDB文件时的数据库状态


RDB文件创建

有两个redis命令可以用于生成RDB文件,一个是SAVE,一个是BGSAVE


save命令执行机制

SAVE命令会阻塞redis服务器进程,执行rdbSave命令直到RDB文件创建完毕为止,在服务器阻塞期间,服务器不能接受任何命令请求


SAVE执行时服务器状态

redis服务器被阻塞,任何请求在阻塞期间都被拒绝


BGSAVE执行机制

服务器进程会fork出一个字进程,由子进程负责执行rdbSave命令创建RDB文件,服务器进程继续处理命令请求


BGSAVE执行时服务器状态

BGSAVE不阻塞redis服务器,redis服务器可以继续处理客户端的命令


BGSAVE期间执行SAVE,BGSAVE,BGREWRITEAOF命令的情况

1,BGSAVE期间禁止执行SAVE命令,避免服务进程与子进程同时执行rdbSave而产生竞争

2,BGSAVE期间也禁止执行BGSAVE命令,避免两个子进程同时调用rdbSave而产生竞争

3,BGRWITEAOF命令与BGSAVE不能同时执行。如果BGSAVE命令正在执行,那么客户端发送BGRWITEAOF的命令会被延迟到BGSAVE命令执行完成之后才执行;如果BGREWRITEAOF命令正在执行,客户端发送的BGSAVE命令会被服务器拒绝


RDB文件载入

RDB文件的载入工作是在服务器启动时自动执行的,所以redis并没有专门的载入RDB文件的命令,只要redis检测到RDB文件就会自动载入


问题:当同时开启AOF持久化功能,rdis如何执行文件加载

如果服务器开启了AOF功能,由于AOF的更新频率要高于RDB的,所以redis服务器会优先使用AOF文件来执行refis内存数据库还原的


RDB自动间隔性保存


自动保存配置

由于redis服务器的BGSAVE命令可以在不阻塞服务器进程的情况下执行,所以redis允许用户可以通过设置服务器的配置save选项,让服务器每隔一段时间自动执行一次BGSAVE命令;用户可以通过为save选项设置多个保存条件,只要其中一个条件满足,服务器就执行BGSAVE命令;具体在redis.conf配置文件中配置


如图可知,命令模式:save <seconds> <changes>;当满足于在seconds里满足changes时,自动触发BGSAVE


检查是否满足自动保存

redis服务器周期操作函数serverCron默认每100ms执行一次扫描,检查save选线设置的保存条件是否满足,如果满足就执行BGSAVE命令


RDB方式总结

SAVE命令写RDB文件会阻塞redis主进程

BGSAVE命令通过redis主进程fork子进程来写RDB文件,redis利用fork的copy-on-write机制拷贝父进程当前所有状态包括内存,然后执行RDB文件写入,写入过程里,父进程依旧接受客户端写命令,所以RDB文件是非实时的,丢失了执行BGSAVE命令期间父进程所执行的写命令数据

RDB自动间隔性保存是基于BGSAVE实现

由于RDB方式的时间粒度粗,而且无法做到实时保存,所以不适合做容灾,适合做数据冷备


redis的AOF持久化机制

AOF方式是通过保存redis服务器所执行的写命令来记录数据库状态,被写入AOF文件的所有命令都是以redis的命令请求协议保存的,因为redis的命令请求是纯文本格式


AOF持久化功能实现

AOF持久化功能实现可以分为命令追加,文件写入,文件同步三步

redis的服务器进程就是一个事件循环(event-loop);循环中文件事件负责接收客户点命令请求并向客户端发送命令回复;时间事件负责执行serverCron函数这种需要定时运行的函数

事件循环(event-loop)-伪代码

命令追加

服务器在执行完写命令之后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区末尾


AOF文件写入和同步

事件循环(event-loop)结束之前,调用flushAppendOnlyFile函数,根据服务器配置属性appendfsync的定义,选择执行将aof_buf缓冲区写入保存到AOF文件里

flushAppendOnlyFile的函数行为由服务器配置的appendfsync选项值来决定

appendfsync=always:服务器在每个事件循环结束之前都会将aof_buf内容写入AOF文件中,并且同步AOF文件落盘;该配置是安全性最高的,即使故障停机也只会丢失一个事件循环(event-loop)中所产生的命令;但是效率是三个选项中最差的,因为频繁的IO以及文件同步

appendfsync=everysec:服务器将每个事件循环(event-loop)都会将aof_buf缓冲区所有内容写入AOF文件,并且每隔一秒就在子线程中对AOF文件做文件同步落盘,属于最实用的配置,保障了效率,且安全性方面丢失一秒数据

appendfsync=no:服务器将每个事件循环(event-loop)都会将aof_buf缓冲区所有内容写入AOF文件,但是不执行主动文件同步落盘,至于何时同步文件由操作系统机制决定,效率方面最快,安全性最差,丢失上次同步AOF文件之后的所有命令


AOF文件载入和数据还原

AOF文件包含了构建数据库状态的所有写命令,所以服务器只要读取并重新执行一遍AOF文件中保存的写命令,就可以还原服务器关闭之前的数据库状态


读取AOF并还原数据库状态步骤

1,创建一个不带网络连接的伪客户端(fake-client)

2,从AOF中分析并读取一条写命令

3,使用伪客户端执行写命令

4,重复执行步骤2,3直到AOF文件被完整执行


AOF重写

AOF通过保存被执行的写命令来记录数据库状态,所以随着时间流逝,AOF文件内容会越来越多,文件体积会越来越大,如果不加约束控制,体积过大的AOF文件可能会对redis服务器造成影响,而且使用AOF恢复数据校验状态的操作时间会更久

为了解决AOF文件体积膨胀问题,redis提供AOF文件的重写功能,通过AOF重写功能可以创建一个新的AOF文件来替代现有AOF文件,新旧两个AOF文件保存的数据库状态相同,但是新AOF文件不会包含任何浪费空间的冗余命令,所以新AOF文件通常会比AOF文件体积小很多


AOF重写实现

AOF重写实现原理:redis首先从数据库读取现有key的value,然后用一条命令去记录当前键值对,代替之前记录的这个键值对的所有命令;所以AOF重写生成的新AOF文件只包含还原当前数据库状态所必须的命令所以新AOF文件不会浪费任何磁盘空间


AOF后台重写(BGREWRITEAOF)

aof_rewrite函数可以很好的完成创建一个新的AOF文件的任务,但是这个函数会执行大量的写入操作,所以调用这个函数的线程会被长时间阻塞,所以当redis服务器直接调用aof_rewrite函数重写AOF文件期间,服务器将无法处理客户端任何命令请求;作为一种辅助手段,redis肯定不希望AOF重写造成服务器不可用,所以redis使用开启子进程的方式重写AOF


后台重写AOF好处:

1,子进程进行AOF重写期间,服务器进程可以继续处理命令

2,子进程带有服务进程的数据副本,使用子进程而非子线程的原因:避免使用锁的情况下保证了数据安全


后台重写的问题:

子进程重写AOF时,主进程还在执行客户端写命令,导致重写之后的AOF文件与redis数据库状态不一致


后台重写问题解决:

redis设置了AOF重写缓冲区,这个缓冲区在子进程开始AOF重写时开始使用,当主进程执行了客户端的写命令,会将这条被执行的写命令同时发送到AOF缓冲区以及AOF重写缓冲区;当AOF重写完成,子进程向主进程发送一个信号,主进程收到信号之后,会将AOF重写缓冲区内所有内容写入新的AOF文件,保证了新AOF与当前redis数据库状态一致,然后将新AOF文件改名,原子覆盖原AOF文件,完成新旧AOF文件替换


AOF持久化方式总结

AOF通过保存修改数据库状态的写命令来记录服务器的数据库状态

AOF机制是先将写命令写入aof_buf,然后根据appendfsync属性定义来执行不同文件写入同步策略

appendfsync属性本设置为always时安全度最高只会丢失一个event-loop中的写命令,被设置为no时安全度最低会丢失自上次之后的所有写命令,而everysec最实用,丢失一秒,性能效率稳健

AOF重写是为了避免AOF文件记录冗余的键值对命令导致文件体积膨胀影响服务器性能;它的机制是生成新不包含冗余键值对命令的AOF文件来替代旧AOF文件;它的实现方式是遍历AOF文件读取数据库中键值对并记录的方式

AOF后台重写是开启新的子进程,开辟AOF重写缓冲区的方式实现,实现方式子进程执行AOF重写,主进程将AOF重写期间的写命令会同步到aof缓冲区以及aof重写缓冲区,当子进程AOF重写完成,通知主进程将AOF重写缓冲区的数据写入到新AOF文件中,而后原子性的重命名并替换旧AOF,后台AOF重写完成

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