AOF - 969251639/study GitHub Wiki

AOF是redis持久化的一种方式,其本质上是通过保存服务器所执行的写命令来记录
其实现主要分为追加(append),文件写入,文件同步(sync)三个步骤:

  1. 命令追加
    服务器执行写完一个命令之后,会以协议格式将被执行的写命令追加到服务器的aof_buf缓冲区id末尾
  2. 文件写入
    调用flushAppendOnlyFile函数,考虑是否需要将aof_buf缓冲区的内容写入和保存到AOF文件里面,其中flushAppendOnlyFile的行为由服务器配置的appendfsync选项决定,分三种情况
  • always:每次主循环执行过程中将aof_buf缓冲区的内容写入并同步到AOF文件里面
  • everysec(默认配置):每隔一秒种将aof_buf缓冲区的内容写入并同步到AOF文件里面,这个同步操作是由一个线程专门负责
  • no: 将aof_buf缓冲区的内容写入到AOF文件,但并不对AOF文件进行同步,何时同步交由操作系统决定
  1. 文件同步
    将操作系统内核中的缓冲区真正的写入到磁盘文件中

AOF的载入:

  1. 创建一个不带网络连接的伪客户端(因为redis的命令只能在客户端上下文中执行,而载入AOF文件时所使用的命令直接来源于AOF文件而不是网络连接,所以服务器使用了一个没有网络连接的伪客户端来执行写请求命令)
  2. 从AOF文件中分析并读取写命令
  3. 使用伪客户端执行被读出的写命令

AOF重写:
AOF的重写主要是执行BGREWRITEAOF命令来实现,这个实现不需要对现有的AOF文件进行任何的读写操作
AOF重写是将其放到子进程中执行,这样AOF重写期间,服务器进程(父进程)可以继续处理命令请求,也可以避免锁,但在AOF重写期间,服务器还要继续处理命令请求,而新的命令可能会对现有的数据库状态进行改写,从而使得服务当前数据库状态和重写后的AOF文件所保存的数据库状态不一致。

为了解决数据不一致问题,redis服务器设置了一个AOF重写缓冲区,当redis服务器执行完一个写命令后,同时也会将这个写命令发送给AOF缓冲区和AOF重写缓冲区,子进程执行AOF重写期间,服务器进程需要执行以下三个功过:

  1. 执行客户端发来的写命令
  2. 将执行后的写命令追加到AOF缓冲区
  3. 将执行后的写命令追加到AOF重写缓冲区
    这样就可以保证
  • AOF缓冲区的内容会定期的被写入和同步到AOF文件
  • 从创建子进程开始,服务器执行的所有写命令都会被记录到AOF重写缓冲区
    当子进程完成AOF重写工作后,会向父进程发送一个信号,父进程接受到该信号后,会调用一个信号处理函数,执行以下工作:
  1. 将AOF重写缓冲区中的所有内容写入到新AOF文件中,这时新的AOF文件所保存的数据库状态与当前服务器状态一致
  2. 对新的AOF文件进行更名,覆盖原有的AOF文件