关注公众号:xy的技术圈linux
众所周知,Redis是一个内存数据库。但它与其它内存数据库(如memcache)等有一个很大的区别,就是Redis能够持久化到磁盘。有了持久化方案,Redis就能够对数据进行备份、恢复、复制。redis
Redis提供了两种持久化方案:RDB和AOF。在Redis 4.0中,提供了一个新特性:二者的混合持久化。下面将介绍Redis的各类持久化方案的原理和配置。数据库
使用info persistence
命令能够查看当前全部有关持久化的信息:安全
RDB持久化是经过快照方式来完成的。当达到触发条件时,Redis会自动将内存中全部数据以二进制方式生成一份副本并存储在硬盘上。服务器
在配置文件能够配置当前配置的备份文件和目录,使用config
命令也能够查看和设置:markdown
RDB分为主动触发和被动触发。app
主动触发指的是客户端执行save
和bgsave
命令会进行持久化。函数
执行save会使Redis处于阻塞状态,不会响应任何其余客户端发来的请求,直到RDB快照文件执行完毕,须要谨慎使用。oop
bgsave即background save,后台保存。当执行bgsave命令时,Redis会fork
出一个子进程来执行快照操做。须要注意的是,在fork子进程的过程当中,Redis是阻塞的。而当子进程建立完成后,Redis就能够继续响应客户端的请求了。性能
子进程建立完成之后,返回“Background saving started”。子进程根据主进程的内存副本建立临时快照文件,当快照文件完成之后对原快照文件进行替换。替换完成后,子进程发送信号给主进程完成快照操做,主进程更新统计信息(info Persistence可查看),子进程退出。
被动触发有好几种状况,下面分别介绍一下。
save m n规则触发
在指定的m秒内,Redis中有n个键发生改变,则自动触发bgsave。该规则默认在redis.conf中进行了配置,而且可组合使用,知足其中一个规则,则触发bgsave
好比save 900 1
,代表当900秒内至少有1个键发生改变时候,Redis会触发bgsave操做。
flushall触发
flushall命令用于清空数据库,请慎用,当咱们使用了则代表咱们须要对数据进行清空,那Redis固然须要对快照文件也进行清空,因此会触发bgsave。
shutdown触发
Redis在关闭前处于安全角度将全部数据所有保存下来,以便下次启动会恢复。可使用客户端连入执行shutdown命令,也能够直接使用脚本关闭Redis,都会在退出前先执行save。
shutdown命令还能够传递一个参数save/nosave。若是使用nosave参数,则不会进行持久化,直接退出。
主从复制触发
在Redis主从复制中,从节点执行全量复制操做,主节点会执行bgsave命令,并将rdb文件发送给从节点。
当Redis意外崩溃或者关闭再次启动时,此时AOF持久化未开启时(默认未开启),将使用RDB快照文件恢复数据。关掉Redis服务再重启,会发现日志里面有:
DB loaded from disk
默认状况下,Redis是关闭了AOF持久化,开启AOF经过配置appendonly为yes开启,咱们修改配置文件或者在命令行直接使用config set修改,在用config rewrite同步到配置文件。经过客户端修改好处是不用重启Redis,AOF持久化直接生效。
若是说RDB至关于数据库的定时备份(冷备),那AOF就至关于数据库的热备。
经过前面的介绍会发现,若是使用RDB,在乎外状况下,好比Redis服务忽然宕机,这个时候有些内存里面的数据还没来得及刷新进磁盘,就会致使一部分数据丢失。
AOF就是用来解决这个问题的。AOF是Append Only File的缩写,AOF能够将Redis执行的每一条写命令追加到磁盘文件中,在Redis启动时候优先选择从AOF文件恢复数据。
由于每一次写操做,都须要记录到文件中,因此开启AOF持久化会对性能有必定的影响,可是大部分状况下这个影响是能够接受的,咱们可使用读写速率高的硬盘提升AOF性能。与RDB持久化相比,AOF持久化数据丢失更少,其消耗内存更少(RDB方式执行bgsve会有内存拷贝)。
AOF实现本质是基于Redis通信协议,将命令以纯文本的方式写入到文件中。
redis协议:
首先Redis是以行来划分,每行以\r\n行结束。每一行都有一个消息头,消息头共分为5种分别以下:
+
表示一个正确的状态信息,具体信息是当前行后面的字符。
-
表示一个错误信息,具体信息是当前行后面的字符。
*
表示消息体总共有多少行,不包括当前行,后面是具体的行数。
$
表示下一行数据长度,不包括换行符长度\r\n,后面则是对应的长度的数据。
:
表示返回一个数值,后面是相应的数字节符。
1 追加写入
Redis将每一条写命令以Redis通信协议添加至缓冲区aof_buf,这样的好处在于在大量写请求状况下,采用缓冲区暂存一部分命令随后根据策略一次性写入磁盘,这样能够减小磁盘的I/O次数,提升性能。
2 同步命令到硬盘
当写命令写入aof_buf缓冲区后,Redis会将缓冲区的命令写入到文件,Redis提供了三种同步策略,由配置参数appendfsync决定,下面是每一个策略所对应的含义:
3 文件重写(bgrewriteaof)
当开启的AOF时,随着时间推移,AOF文件会愈来愈大,固然Redis也对AOF文件进行了优化,即触发AOF文件重写条件的时候,Redis将使用bgrewriteaof对AOF文件进行重写。这样的好处在于减小AOF文件大小,同时有利于数据的恢复。重写策略:
AOF文件重写过程与RDB快照bgsave工做过程有点类似,都是经过fork子进程,由子进程完成相应的操做,一样的在fork子进程简短的时间内,Redis是阻塞的,过程如图:
过程说明:
1.开始bgrewriteaof,判断当前有没有bgsave命令(RDB持久化)/bgrewriteaof在执行,假若有,则这些命令执行完成之后再执行。
2.主进程fork出子进程,在这一个短暂的时间内,redis是阻塞的。
3.主进程fork完子进程继续接受客户端请求,全部写命令依然写入AOF文件缓冲区并根据appendfsync策略同步到磁盘,保证原有AOF文件完整和正确。因为fork的子进程仅仅只共享主进程fork时的内存,所以Redis使用采用重写缓冲区(aof_rewrite_buf)机制保存fork以后的客户端的写请求,防止新AOF文件生成期间丢失这部分数据。此时,客户端的写请求不只仅写入原来aof_buf缓冲,还写入重写缓冲区(aof_rewrite_buf)。
4.子进程经过内存快照,按照命令重写策略写入到新的AOF文件。
4.1子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。
4.2主进程把aof_rewrite_buf中的数据写入到新的AOF文件。
5.使用新的AOF文件覆盖旧的AOF文件,标志AOF重写完成。
重写的触发条件:
AOF文件触发条件可分为手动触发和自动触发。
手动触发:客户端执行bgrewriteaof命令。
自动触发:自动触发经过如下两个配置协做生效:
Redis开启在AOF功能开启的状况下,会维持如下三个变量
每次当serverCron(服务器周期性操做函数)函数执行时,它会检查如下条件是否所有知足,若是所有知足的话,就触发自动的AOF重写操做:
当AOF开启时候,Redis数据恢复优先选用AOF进行数据恢复。关掉Redis服务再重启,会发现日志里面有:
DB loaded from append only file
RDB的优势:
RDB文件体积小,所以在传输速度上较快,适合灾难恢复。RDB使Redis性能更高,子进程处理保存工做。在恢复大数据集时比AOF恢复速度快。
AOF的优势:
数据更完整和安全,秒级数据丢失(取决于appendfsync策略)。兼容性高,由于是基于Redis通信协议造成的明文文件,因此容易阅读,且任何版本的Redis都兼容。
混合持久化是Redis 4.0才有的功能。
混合持久化一样也是经过bgrewriteaof完成的,不一样的是当开启混合持久化时,fork出的子进程先将共享的内存副本以RDB方式写入AOF文件,而后在将重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,并将新的AOF文件替换旧的的AOF文件。
简单的说:新的AOF文件前半段是RDB格式的全量数据,后半段是AOF格式的增量数据。
使用混合持久化后,Redis依然优先加载AOF文件。可能有两种状况:
4.0版本的混合持久化默认关闭的,经过aof-use-rdb-preamble
配置参数控制,yes则表示开启,no表示禁用,默认是no,可经过config set
修改。
混合模式能够结合AOF和RDB的优势,可以快速加载的同时避免丢失过多的数据。
认真写文章,用心作分享。
我的网站:yasinshaw.com
公众号:xy的技术圈