Redis学习笔记9之Redis的持久化机制、数据恢复、AOF后台重写问题

目录

redis持久化机制

恢复数据

AOF后台重写


redis持久化机制

为了避免数据的丢失而采用的记录数据(备份数据)的方式
持久化的时机:

  • 1、服务器重启
  • 2、设置持久化的周期

两种方式:

RDB:默认开启。二进制文件(dump.rdb)转出文件,随数据的增多而越来越大

Save the DB on the disk
提供了默认触发持久化的时机的参数配置:
60s改了一万次,
5分钟改了十次,
15分钟改了一次等都会出发save the DB on the disk
save second <操作的次数change>

AOF:append of file 手动开启,记录操作的日志文件(操作一条数据就写一条日志的方式)
第1步、开启aof,进入redis.conf配置文件,将appendonly no改为yes,appendfilename日志文件默认为appendonly.aof
第2步、配置哪时写入,修改为appendfsync everysec
有三种策略:
appendfsync always 有操作就写入,频率太高了
appendfsync everysec 一秒写入一次,最多只会丢失一秒的数据
appendfsync no 不开启写入

 

恢复数据

查看appendonly.aof文件,其实就是将指令写进去。

恢复数据,其实就是重新执行一次指令。

弊端:恢复的方式很简单,比如一个key执行了很多次修改的指令,其实应该只要执行这个key的最后一次更新语句就可以了。

针对这个问题的优化:

设置重写时机,设置文件大小,超过设置的条件后,再重写(没必要每次检查到相同key的操作就重写,效率低且耗时):

auto-aof-rewrite-percentage 100  #百分百重写的比例

auto-aof-rewrite-min-size 64mb   #超过64m

 

那么重写的时机出发了,具体怎么重写?(重写的意思不是对原有AOF文件相同key操作的比较)

直接将内存中的最新的数据,以指令的方式写入到文件中。

PS:AOF重写并不需要对原有AOF文件进行任何的读取,写入,分析等操作。这个功能是通过读取服务器当前的数据库状态来实现的。

aof重写机制参考:

https://www.jianshu.com/p/f72008c4d49f

 

AOF后台重写

  1. aof_rewrite函数可以创建新的AOF文件,但是这个函数会进行大量的写入操作,所以调用这个函数的线程将被长时间的阻塞,因为Redis服务器使用单线程来处理命令请求;所以如果直接是服务器进程调用AOF_REWRITE函数的话,那么重写AOF期间,服务器将无法处理客户端发送来的命令请求;
  2.     Redis不希望AOF重写会造成服务器无法处理请求,所以Redis决定将AOF重写程序放到子进程(后台)里执行。这样处理的最大好处是:
  •         子进程进行AOF重写期间,主进程可以继续处理命令请求;
  •         子进程带有主进程的数据副本,使用子进程而不是线程,可以避免在锁的情况下,保证数据的安全性。

 

使用子进程进行AOF重写的问题

子进程在进行AOF重写期间,服务器进程还要继续处理命令请求,而新的命令可能对现有的数据进行修改,这会让当前数据库的数据和重写后的AOF文件中的数据不一致。

 

如何修正

为了解决这种数据不一致的问题,Redis增加了一个AOF重写缓存,这个缓存在fork出子进程之后开始启用,Redis服务器主进程在执行完写命令之后,会同时将这个写命令追加到AOF缓冲区和AOF重写缓冲区。
即fork出的子进程在执行AOF重写时,主进程需要执行以下三个工作:

  1.         执行client发来的命令请求;
  2.         将写命令追加到现有的AOF文件中;
  3.         将写命令追加到AOF重写缓存中。

Redis学习笔记9之Redis的持久化机制、数据恢复、AOF后台重写问题

 

效果

  • 可以保证: 
    • AOF缓冲区的内容会定期被写入和同步到AOF文件中,对现有的AOF文件的处理工作会正常进行
    • 从创建子进程开始,服务器执行的所有写操作都会被记录到AOF重写缓冲区中;

完成AOF重写之后

  • 当子进程完成对AOF文件重写之后,它会向父进程发送一个完成信号,父进程接到该完成信号之后,会调用一个信号处理函数,该函数完成以下工作:

    • 将AOF重写缓存中的内容全部写入到新的AOF文件中;这个时候新的AOF文件所保存的数据库状态和服务器当前的数据库状态一致;
    • 对新的AOF文件进行改名,原子的覆盖原有的AOF文件;完成新旧两个AOF文件的替换。
  • 当这个信号处理函数执行完毕之后,主进程就可以继续像往常一样接收命令请求了。在整个AOF后台重写过程中,只有最后的“主进程写入命令到AOF缓存”和“对新的AOF文件进行改名,覆盖原有的AOF文件。”这两个步骤(信号处理函数执行期间)会造成主进程阻塞,在其他时候,AOF后台重写都不会对主进程造成阻塞,这将AOF重写对性能造成的影响降到最低。

以上,即AOF后台重写,也就是BGREWRITEAOF命令的工作原理。