1.什么是AOF
每执行完一条写命令,就把命令追加到AOF文件,在数据恢复时,再逐一执行里面的命令进行数据恢复。
先写操作,后记录的优势:
1.不需要额外的检查开销
因为如果先记录,再执行的话。需要在记录之前,考虑语法是否正确,是否能执行。否则会出现记录完了,无法执行的情况。
2.避免了写操作被阻塞。因为是写完之后,才记录的。不存在因记录出错,而阻塞后续 的写操作执行。
坏处:
1.数据丢失:还没有写回硬盘你,服务器就宕机了
2.下一个命令被阻塞:因为将命令写到日志这个操作是写进程完成的,执行命令也是写进程,所以两个操作是同步的。
2.写入AOP日志过程
用户发起命令,主线程执行命令,命令追加到 AOF缓冲区(aof_buf)中,然后用户调用 write 函数切换到内核态,然后将数据拷贝到 内核缓冲区(page cache)中,通过系统调用 fsync函数 将内核缓冲区数据写到硬盘中。
控制 fsync 的调用时机有三种方式,可以通过修改 redis.conf 配置文件中的 appendfsync 选项来进行控制:
Always:主进程的主线程控制,写命令执行完了就立刻写入AOF文件
EverySec:子线程执行,AOF缓冲区每隔一秒,就将数据写到硬盘
No:操作系统
可靠性从高到低,性能从低到高
底层源码里面,这三种策略是在控制 fsync() 的调用时机,来觉得何时将AOF缓冲区的数据写回硬盘
3.重写机制
文件太大了性能不好,数据恢复慢,所以有重写机制,目的是减小AOF文件。
过程:
直接扫描数据中所有键值对数据,然后为每一个键值对生成一条写命令,再将写命令写入到新的AOF文件。重写过程是由子进程 bgrewriteaof 完成的,这个可以使主进程继续正常的处理命令。
Redis 有一个 AOF 重写缓冲区,在 fork 子进程了之后开始使用。redis执行完 写命令 之后,会将写命令同时发给 AOF缓冲区 和 AOF重写缓冲区。
子进程完成重写之后,会向主进程发一个信号,主进程调用信号处理函数,完成以下功能:
1.AOF重写缓冲区 中的内容追加到新AOF文件中,使新旧AOF的数据库状态一致
2.新AOF改名并 覆盖旧AOF