AOF与RDB持久化经过保存数据库中的键值对来记录数据库状态不一样,aof持久化是经过保存redis服务器所执行的写命令来记录数据库状态的。被写入AOF文件的全部命令都是以Redis的命令请求协议格式保存的。redis
AOF持久化的实现能够分为命令追加(append),文件写入,文件同步(sync)三个步骤。数据库
当AOF持久化功能处于打开状态,服务器在执行完一个写命令以后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区末尾:bash
struct redisServer{ //... //AOF缓冲区 sds aof_buf //... };
例如 redis>SET KEY VALUE服务器
那么服务器在执行这个set命令以后,会将如下协议内容追加到aof_buf缓冲区的末尾:网络
*3\r\n$3\r\nSET\r\n$3\r\nKEY\r\n$5\r\nVALUE\r\napp
redis服务器进程就是一个事件循环(loop),这个循环中的文件事件负责接收客户端的命令请求,以及向客户端发送命令回复,而时间事件则负责执行像serverCron函数这样须要定时运行的函数。函数
由于服务器在处理文件事件时可能会执行写命令,使得一些内容被追加到aof_buf缓冲区里面,因此在服务器每次结束一个事件循环以前,它都会调用flushAppendOnlyFile函数,考虑是否须要将oop
aof_buf缓冲区的内容写入和保存到AOF文件里面。server
def eventLoop(): while true: //处理文件事件,接收命令请求以及发送命令回复 //处理命令请求时可能会有新内容被追加到aof_buf缓冲区 processFileEvents() //处理时间事件 processTimeEvents() //考虑是否将aof_buf中的内容写入和保存到AOF文件里面 flushAppendOnlyFile()
flushAppendOnlyFile函数的行为由服务器配置的appendfsync选项的值来决定,各个不一样值产生的行为以下表所示:blog
appendfsync默认值是everysec,能够参考redis.conf配置文件
假设服务器在处理文件事件期间,执行了一些写命令。若是这时flushAppendOnlyFile函数被调用,假设服务器当前的appendfsync的值是everysec,而且距离上次同步AOF文件已经超过1秒钟,那么服务器会先将aof_buf中的内容写入到AOF文件中,而后再对AOF文件进行同步。
由于AOF文件里面包含了重建数据库状态所需的全部写命令,因此服务器只要读入并从新执行一遍AOF文件里面保存的写命令,就能够还原服务器关闭以前的数据库状态。
redis读取AOF文件并还原数据的具体步骤以下:
1)建立一个不带网络链接的伪客户端:由于redis的命令只能在客户端上下文中执行,而载入aof文件时所使用的命令直接来源于AOF文件而不是网络链接,因此服务器使用伪客户端来执行aof文件保存的写命令,伪客户端执行命令的效果和带网络链接客户端执行命令的效果彻底同样。
2)从AOF文件中分析并读取一条写命令
3)使用伪客户端执行被读出的写命令
4)一直执行步骤2和步骤3,知道文件读取完毕
其实就是为了解决AOF文件体积膨胀的问题,Redis提供了AOF文件重写功能。
aof重写程序是放在子进程里执行的