1、AOF文件通过保存修改数据库的写命令请求来记录服务器的数据库状态
所有命令都是以Redis命令请求协议的格式进行保存。AOF持久化功能的实现是通过命令追加、文件写入、文件同步三个步骤来完成的。
(1)当AOF持久化功能开启时,在执行数据库的写入命令时,服务器会将该写入命令加入到redisServer所维护的一个aof_buf缓存区的末尾。
(2)文件进行写入时,因为 Redis服务器进程是一个事件循环,在每次执行事件循环的过程中,可以理解为文件事件负责接收客户端的命令请求,以及向客户端返回命令回复,而时间事件负责执行类似于serverCron函数这样的周期性函数。 回到文件写入,每次循环事件执行时,都会调用flushAppendOnlyFile函数,考虑是否需要将aof_buf缓冲区的内容写入到AOF文件中,而至于函数如何控制学日和同步,则是通过下面提到的配置选项来决定的。
2、appendfsync选项的不同值会对AOF持久化的安全性和服务器的性能造成很大程度的影响
对于服务器何时将缓冲区的内容写入并同步到AOF文件中,Redis服务器通过上面提到的appendfsync选项的不同值来决定:
always => 将缓冲区的所有内容都写入并同步到AOF文件中。
everysec => 将缓冲区的内容写入到AOF文件中,如何距离上次同步已经超过了一秒钟,那么再次对AOF文件进行同步,需要注意的是,会有专门的线程来负责该同步操作。
no => 将缓冲区的内容写入AOF文件中,但是不对文件做同步操作,至于何时来同步,由操作系统来决定。
3、服务器在加载AOF文件时,是通过重新执行其中的请求命令进行还原数据库的状态
在重新加载AOF文件中写入命令来还原数据库的状态的过程,可分为以下步骤:
(1)创建一个不带网络连接的伪客户端(fake client),因为该客户端只需要执行AOF文件中的写入命令,以此来完成数据库装态的恢复,所以,不需要进行网络连接。
(2)从AOF文件中分析并读取出写命令。
(3)使用伪客户端执行这条写命令。
(4)反复执行步骤(2)和步骤(3),直到AOF文件中的写入命令执行结束,这样数据库状态就得到了恢复。
4、AOF重写会产生一个新的AOF文件,只不过相比之下,体积更小
随着时间的流逝和业务不断的扩展,会使得数据库中数据的不断膨胀,Redis服务器执行的写入命令也会不断地累积,对于服务器来说,将所有的写入命令保存下来,写入到AOF文件中,冒失不是非常合理,这也不符合开发逻辑,所以,在AOF重写产生新的AOF文件时,服务器会先读取数据库中的值,而是用一条写入命令来表示当前数据库的状态,这样,AOF文件的提及会变得小很多,同时,在加载过程中,也会减轻服务器的压力。
5、在执行BGREWRITEAOF命令时,Redis服务器会维护一个AOF重写缓存区,该缓存区的作用就是,在子进程创建新的AOF文件时,记录服务器执行的所有的写命令。
因为Redis服务器使用单线程来处理命令请求,当服务器调用aof)_rewrite函数,创建新的AOF文件过程中,服务器将无法处理客户端发来的命令请求。所以,为了提高Redis服务器的高效使用,我们将AOF重写操作放到子进程里来完成。
而上面这种方法会引发一个问题,既然要还原数据库的状态,肯定要确保数据的一致性,也就是不能漏掉任何一个数据库写入命令。Redis服务器通过维护一个AOF重写缓存区来进行追加AOF文件重写过程中服务器执行的命令请求操作。在子进程AOF文件重写结束后,服务器进程会将AOF重写缓存区的命令追加到新的AOF文件的末尾。 这也是AOF后台重写的原理,就简单介绍到这里。