redis-rdb&aof

RDB

RDB是在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。

优势:使用单独子进程来进行持久化,主进程不会进行任何IO操做,保证了redis的高性能

缺点:RDB是间隔一段时间进行持久化,若是持久化之间redis发生故障,会发生数据丢失。因此这种方式更适合数据要求不严谨的时候
复制代码

配置信息

save 900 1
save 300 10
save 60 10000
snapshot触发的时机,是有“间隔时间”和“变动次数”共同决定,同时符合2个条件才会触发snapshot,不然“变动次数”会被继续累加到下一个“间隔时间”上。snapshot过程当中并不阻塞客户端请求。snapshot首先将数据写入临时文件,当成功结束后,将临时文件重名为dump.rdb。
复制代码

RDB触发机制

1.save命令:阻塞当前redis服务器,直到RDB过程完成为止,若是redis数据较多,可能形成redis进程的长时间阻塞。

2.bgsave: redis执行fork建立子进程,RDB持久化过程由这个子进程负责,完成以后结束。
复制代码

流程图

RDB恢复数据

RDB文件的载入工做是在服务器启动时自动执行的,并无专门的命令。可是因为AOF的优先级更高,所以当AOF开启时,Redis会优先载入AOF文件来恢复数据;只有当AOF关闭时,才会在Redis服务器启动时检测RDB文件,并自动载入。服务器载入RDB文件期间处于阻塞状态,直到载入完成为止。

Redis载入RDB文件时,会对RDB文件进行校验,若是文件损坏,则日志中会打印错误,Redis启动失败。
复制代码

AOF

  • Append-only file,将“操做 + 数据”以格式化指令的方式追加到操做日志文件的尾部,在append操做返回后(已经写入到文件或者即将写入),才进行实际的数据变动,“日志文件”保存了历史全部的操做过程;当server须要数据恢复时,能够直接replay此日志文件,便可还原全部的操做过程。AOF相对可靠,它和mysql中bin.log、apache.log、zookeeper中txn-log简直殊途同归。AOF文件内容是字符串,很是容易阅读和解析。mysql

  • 优势:能够保持更高的数据完整性,若是设置追加file的时间是1s,若是redis发生故障,最多会丢失1s的数据;且若是日志写入不完整支持redis-check-aof来进行日志修复;AOF文件没被rewrite以前(文件过大时会对命令进行合并重写),能够删除其中的某些命令(好比误操做的flushall)。linux

  • 咱们能够简单的认为AOF就是日志文件,此文件只会记录“变动操做”(例如:set/del等),若是server中持续的大量变动操做,将会致使AOF文件很是的庞大,意味着server失效后,数据恢复的过程将会很长;事实上,一条数据通过屡次变动,将会产生多条AOF记录,其实只要保存当前的状态,历史的操做记录是能够抛弃的;由于AOF持久化模式还伴生了“AOF rewrite”。redis

  • AOF的特性决定了它相对比较安全,若是你指望数据更少的丢失,那么能够采用AOF模式。若是AOF文件正在被写入时忽然server失效,有可能致使文件的最后一次记录是不完整,你能够经过手工或者程序的方式去检测并修正不完整的记录,以便经过aof文件恢复可以正常;同时须要提醒,若是你的redis持久化手段中有aof,那么在server故障失效后再次启动前,须要检测aof文件的完整性。sql

  • AOF是文件操做,对于变动操做比较密集的server,那么必将形成磁盘IO的负荷加剧;此外linux对文件操做采起了“延迟写入”手段,即并不是每次write操做都会触发实际磁盘操做,而是进入了buffer中,当buffer数据达到阀值时触发实际写入(也有其余时机),这是linux对文件系统的优化,可是这却有可能带来隐患,若是buffer没有刷新到磁盘,此时物理机器失效(好比断电),那么有可能致使最后一条或者多条aof记录的丢失。经过上述配置文件,能够得知redis提供了3中aof记录同步选项:数据库

  • 其实,咱们能够选择的太少,everysec是最佳的选择。若是你很是在乎每一个数据都极其可靠,建议你选择一款“关系性数据库”吧。AOF文件会不断增大,它的大小直接影响“故障恢复”的时间,并且AOF文件中历史操做是能够丢弃的。**AOF rewrite操做就是“压缩”AOF文件的过程,固然redis并无采用“基于原aof文件”来重写的方式,而是采起了相似snapshot的方式:基于copy-on-write,全量遍历内存中数据,而后逐个序列到aof文件中。所以AOF rewrite可以正确反应当前内存数据的状态,这正是咱们所须要的;**rewrite过程当中,对于新的变动操做将仍然被写入到原AOF文件中,同时这些新的变动操做也会被redis收集起来(buffer,copy-on-write方式下,最极端的多是全部的key都在此期间被修改,将会耗费2倍内存),当内存数据被所有写入到新的aof文件以后,收集的新的变动操做也将会一并追加到新的aof文件中,此后将会重命名新的aof文件为appendonly.aof,此后全部的操做都将被写入新的aof文件。若是在rewrite过程当中,出现故障,将不会影响原AOF文件的正常工做,只有当rewrite完成以后才会切换文件,由于rewrite过程是比较可靠的。apache

  • 能够经过配置文件来指定它们中的一种,或者同时使用它们(不建议同时使用),或者所有禁用,在架构良好的环境中,master一般使用AOF,slave使用snapshot,主要缘由是master须要首先确保数据完整性,它做为数据备份的第一选择;slave提供只读服务(目前slave只能提供读取服务),它的主要目的就是快速响应客户端read请求;可是若是你的redis运行在网络稳定性差/物理环境糟糕状况下,建议你master和slave均采起AOF,这个在master和slave角色切换时,能够减小“人工数据备份”/“人工引导数据恢复”的时间成本;若是你的环境一切很是良好,且服务须要接收密集性的write操做,那么建议master采起snapshot,而slave采用AOF。安全

aof流程图

1.全部的写入命令都会追加到aof_buf(缓冲区)中。
2.AOF缓冲区根据对应的策略向硬盘中作同步操做。
3.随着AOF文件的增大,须要按期对AOF文件进行重写,达到压缩的目的。
4.当Redis服务器重启的时候,能够加载AOF文件进行数据恢复。
复制代码
  • AOF命令的写入是使用文本协议格式。为何要首先写入到缓冲区,是由于Redis是单线程的,若是每次都追加到硬盘中,那么性能就取决于当前硬盘的负载。
由appendfsync进行控制。

always:每一条aof记录都当即同步到文件,这是最安全的方式,也觉得更多的磁盘操做和阻塞延迟,
是IO开支较大。

everysec:每秒同步一次,性能和安全都比较中庸的方式,也是redis推荐的方式。若是遇到物理服务器故障,
有可能致使最近一秒内aof记录丢失(可能为部分丢失)。

no:redis并不直接调用文件同步,而是交给操做系统来处理,操做系统能够根据buffer填充状况/通道空闲时
间等择机触发同步;这是一种普通的文件操做方式。性能较好,在物理服务器故障时,数据丢失量会因OS配置有关
复制代码

重写机制

1.手动触发:直接调用bgrewriteaof命令
2.自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数来决定自动触发。

auto-aof-rewrite-min-size表示运行AOF重写文件的最小体积
auto-aof-rewrite-percentage表明当前AOF文件空间和上次从写后AOF文件空间的比值。
复制代码

1. 执行AOF重写请求。 若是当前进程正在执行AOF重写,请求执行。
2. 父进程执行fork建立子进程,开销等同于bgsave过程。
3. 主进程fork操做完成后,继续相应其余命令。全部修改命令依然写入AOF缓冲区并根绝appendfsync策略同步到硬盘,保证原有AOF机制正确性。fork操做运用写时复制技术,子进程只能共享fork操做时候的内存数据。因为父进程依然响应命令,redis使用“AOF
重写缓冲区”保存这部分西数据,防止新AOF文件生成期间丢失这部分数据。
4. 子进程依据内存快照,按照命令合并规则写入新的AOF文件。
5.新AOF文件写入完成以后,子进程发送信号给父进程,父进程统计信息。父进程把AOF重写缓冲区的数据写入到新的AOF文件。使用新AOF文件替换老文件,完成AOF重写。
复制代码

重启加载

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息