AOF - 969251639/study GitHub Wiki
AOF是redis持久化的一种方式,其本质上是通过保存服务器所执行的写命令来记录
其实现主要分为追加(append),文件写入,文件同步(sync)三个步骤:
- 命令追加
服务器执行写完一个命令之后,会以协议格式将被执行的写命令追加到服务器的aof_buf缓冲区id末尾 - 文件写入
调用flushAppendOnlyFile函数,考虑是否需要将aof_buf缓冲区的内容写入和保存到AOF文件里面,其中flushAppendOnlyFile的行为由服务器配置的appendfsync选项决定,分三种情况
- always:每次主循环执行过程中将aof_buf缓冲区的内容写入并同步到AOF文件里面
- everysec(默认配置):每隔一秒种将aof_buf缓冲区的内容写入并同步到AOF文件里面,这个同步操作是由一个线程专门负责
- no: 将aof_buf缓冲区的内容写入到AOF文件,但并不对AOF文件进行同步,何时同步交由操作系统决定
- 文件同步
将操作系统内核中的缓冲区真正的写入到磁盘文件中
AOF的载入:
- 创建一个不带网络连接的伪客户端(因为redis的命令只能在客户端上下文中执行,而载入AOF文件时所使用的命令直接来源于AOF文件而不是网络连接,所以服务器使用了一个没有网络连接的伪客户端来执行写请求命令)
- 从AOF文件中分析并读取写命令
- 使用伪客户端执行被读出的写命令
AOF重写:
AOF的重写主要是执行BGREWRITEAOF命令来实现,这个实现不需要对现有的AOF文件进行任何的读写操作
AOF重写是将其放到子进程中执行,这样AOF重写期间,服务器进程(父进程)可以继续处理命令请求,也可以避免锁,但在AOF重写期间,服务器还要继续处理命令请求,而新的命令可能会对现有的数据库状态进行改写,从而使得服务当前数据库状态和重写后的AOF文件所保存的数据库状态不一致。
为了解决数据不一致问题,redis服务器设置了一个AOF重写缓冲区,当redis服务器执行完一个写命令后,同时也会将这个写命令发送给AOF缓冲区和AOF重写缓冲区,子进程执行AOF重写期间,服务器进程需要执行以下三个功过:
- 执行客户端发来的写命令
- 将执行后的写命令追加到AOF缓冲区
- 将执行后的写命令追加到AOF重写缓冲区
这样就可以保证
- AOF缓冲区的内容会定期的被写入和同步到AOF文件
- 从创建子进程开始,服务器执行的所有写命令都会被记录到AOF重写缓冲区
当子进程完成AOF重写工作后,会向父进程发送一个信号,父进程接受到该信号后,会调用一个信号处理函数,执行以下工作:
- 将AOF重写缓冲区中的所有内容写入到新AOF文件中,这时新的AOF文件所保存的数据库状态与当前服务器状态一致
- 对新的AOF文件进行更名,覆盖原有的AOF文件