redis支持两种持久化方式,一种是RDB,一种是AOF。redis
RDB是根据指定的规则定时将内存中的数据备份到硬盘上,AOF是在每次执行命令后命令自己记录下来,因此RDB的备份文件是一个二进制文件,而AOF的备份文件是一个文本文件。数据库
RDB的备份是经过快照来完成的,当符合设定的条件时redis会将内存中的全部数据自动生成一份副本保存到硬盘上,这个保存的过程就是快照。安全
这个条件在配置文件中指定,由两个参数所定义:时间窗口M和改动的键个数N,每当时间M内改动的键个数大于N时,则触发快照备份。服务器
能够同时存在多个快照条件,条件之间是或的关系,也就是说只要有一个条件被触发就会执行快照备份。多线程
save 900 1 : 在15分钟内有至少一个键被修改则触发。
save 300 10 : 在5分钟内至少有10个键被修改则触发。
sae 60 10000 : 在一分钟内有10000个键被修改则触发。app
save命令会让redis同步地执行快照操做,在快照执行的时候会阻塞全部来自客户端的请求,当数据库中的数据比较多时备份时间可能就比较长,就会致使服务器长时间无响应,因此此项在生产环境应该慎用。异步
须要手动执行快照备份的话应该使用bgsave命令,bgsave命令能够在后台异步的执行备份操做,在备份快照的同时服务器仍然可以相应客户端的请求。函数
既然bgsave那么好,为毛还要save呢?
save能够一直阻塞等到结果,可是由于bgsave是多线程,在执行bgsave的时候只是启动一个线程去备份,咱们并不能肯定备份到底有没有成功呢?当指定bgsave的时候老是返回OK,这个OK表示的是开始执行快照操做并非快照操做执行成功,要想知道快照是否执行成功,能够经过lastsave命令获取最近一次成功执行快照的时间,返回结果是一个unix时间戳。优化
当执行flushall的时候redis会清空当前仓库的全部数据,只要自动快照条件不为空的话在清空以前就要执行一次备份,当没有定义快照触发条件的时候执行flushall不会执行备份。spa
当设置了主从模式时,redis会在初始化时自动进行快照。
redis默认会将快照放到当前进程工做目录的dump.db文件中,能够经过配置dir和dbfilename两个参数来指定要保存到的路径和文件名。
为了节省空间,RDB文件是通过压缩的,在硬盘上的占用空间会小于在内存中的占用空间,能够经过rdbcompression参数来禁用掉压缩(可节省些许cpu占用吧)
rdb快照备份的过程(copy-on-write):
1. redis用fork函数复制一份当前进程的副本。
2. 父进程继续接受客户端发来的命令,子进程开始将内存中的数据写到硬盘的临时文件。
3. 当子进程备份完的时候将子进程和父进程的数据合并。
(没看过源代码,上面抄来的... = = )
注: copy-on-write是一种比较经常使用的备份策略。
aof通常用于对数据丢失容忍度不高的状况下,用于对数据保存要求较高的场景。
默认状况下redis是没有开启aof的,使用appendonly来开启(appendonly yes):
能够经过appendfilename来指定aof文件的名字,默认的名字是【appendonly.aof】:
aof文件以纯文本的形式记录了redis执行的命令,它只是傻傻的把执行过的命令往aof文件中添加并不知道添加的是个什么,这样就可能存在一个问题,好比下面连着的两条命令:
set foo bar
set foo baar
在aof文件中会忠实的记录下整个改变的过程,而不是机智的只存储一个set foo baar。
这样子的话aof文件中就可能会存在冗余命令,因此能够设定一个触发条件,设定每到必定条件时就让redis优化aof文件,优化aof文件的策略是与以前aof的内容无关,而是跟当前内存中的数据有关(在内存中都已经不存在的命令没有存在必要了,对于已经存在的只保留最后一次的操做就能够啦),进行设定的参数:
auto-aof-rewrite-percentage : 当前的aof文件超过上一次重写时大小的百分之多少时再次进行重写,若是以前没有重写过,则以启动时的aof文件大小为依据。
auto-aof-rewrite-min-size : 限制容许重写aof文件的最小的大小,好比当aof文件很小的时候有冗余也不要紧的,咱们就不要再去抽出资源来重写它啦,这个是aof文件小于64M则不会进行重写。
每次同步数据库的内容时redis都会将命令记录到aof文件中,可是事实上咱们都知道硬盘是有一个写缓冲区的,要写的东西并不会当即就写到硬盘上而是如今硬盘的缓冲区内待一下子,等到攒够了人头再“拼车”一块儿写入硬盘,在默认状况下操做系统每30秒会执行一次同步操做,会将硬盘缓冲区的内容真正的写入到硬盘,可是在这30秒内若是发生了什么人力不可抗拒因素啥的这数据但是就丢了哇,咱们用aof就是为了尽可能不丢失数据,因此有一个选项appendfsync用来指定同步的策略:
always : 表示每次都会写入硬盘,这是最安全也是最慢的方式(请确保丫硬盘够给力....)。
everysec : 每秒同步一次(默认)
no : 不会主动进行同步,让操做系统看着办吧,操做系统默认的是每30秒将硬盘缓冲区内的数据同步到的硬盘一次。
RDB和AOF能够同时配置的,当同时开启的时候启动的时候redis会加载AOF文件,由于一般状况下AOF持久化保存的数据更完整一些。
参考资料:
1. 《redis入门指南》 第二版