RDB进行Redis的持久化,是将Redis在内存中的二进制数据进行压测保存到文件,在启动Redis时候,Redis会检测是否存在RDB文件,如果存在就会对文件进行分析和恢复。
如果我们没有在配置文件中显式去配置,Redis会有一个默认的RDB配置。
save 900 1 //900秒内发生1次更新 save 300 10 //300秒内发生10次更新 save 60 10000 //60秒内发生10000次更新
三个条件满足任意一个,BGSAVE命令就会被Redis执行。
redisServer由dirty属性以及lastsave属性。
与RDB把内存中二进制数据保存的方式不同,AOF是把更新数据库的命令保存下来。
每一次发生更新命令时,redis会把命令放到aof_buf
中,每次在执行完成命令之后,会判断是否达到备份条件,如果达到就把aof_buf
中的数据保存到AOF文件中。
appendfsync always //每次执行完成更新命令,都会被命令写到AOF文件中 appendfsync everysec //每秒一次,把aof_buf中的命令写道AOF文件中 appendfsync no //由redis执行决定何时同步
如果Redis服务器同时配置了RDB和AOF两种持久化策略,会优先使用AOF进行数据恢复。使用AOF文件进行数据恢复的方式与RDB不同,开始备份时,会创建一个不带网络连接的伪客户端,该客户端来读取AOF中的命令,并一条一条的发送给Redis服务器进行执行。
随着服务器的运行,AOF文件会越来越大,这个时候Redis会对AOF进行重写。进行重写并不是像字面上的意思那样,对AOF文件进行解析重写,Redis在进行AOF重写时,实际上是把数据库中的每一个键值对进行分析,分析成为Redis命令写到新的AOF文件中,完成之后再用新的AOF文件替换旧的AOF文件。
Redis进行AOF的时候,其实也是在后台开启了一个子进程进行AOF的备份,此时在子进程进行AOF备份时,主进程同样可以处理其他命令,这样就会出现在这期间新发生的更新操作没办法记录到AOF的情况,导致数据不一致的情况。为了解决这个问题,在发生AOF重写时,主进程在处理更新请求时,不仅会把命令写道aof_buf
中,同时会写到AOF重写缓冲区
中。当子进程完成AOF重写时,会发送一个信号给主进程,主进程触发信号处理函数,将AOF重写缓冲区中的所有内容写到新的AOF文件中。在信号处理函数执行期间,主进程会阻塞,不在处理其他命令。
无论时RDB备份还是AOF重写都是在后台fork出一个子进程来完成具体操作,这样的好处是,子进程使用的是主进程的数据副本,不会影响主进程的正常使用,需要注意AOF重写时数据一致性的问题。