当AOF持久化功能处于打开状态时,Redis服务器在执行完一个写命令之后,会以协议格式(如上面截图中AOF文件里保存写命令的格式)将被执行的写命令追加到服务器状态的AOF缓冲区的末尾,然后Redis服务器会根据配置文件中appendfsync选项的值来决定何时将AOF缓冲区中的内容写入和同步到AOF文件里面。
appendfsync选项有以下3个值:
always
从安全性来说,always是最安全的(丢失数据最少),因为即使出现故障停机,数据库也只会丢失一个事件循环中所产生的命令数据。
从效率来说,always的效率最慢,因为服务器在每个事件循环都要将AOF缓冲区中的所有内容写入到AOF文件,并且同步AOF文件。
everysec
从安全性来说,everysec模式下,即使出现故障停机,数据库只会丢失一秒钟的命令数据。
从效率来说,everysec模式足够快,因为服务器在每个事件循环都要将AOF缓冲区中的所有内容写入到AOF文件,并且每隔一秒就要在子线程中对AOF文件进行同步。
no
从安全性来说,no模式下,如果出现故障停机,数据库会丢失上次同步AOF文件之后的所有写命令数据,具有不确定性,因为服务器在每个事件循环都要将AOF缓冲区中的所有内容写入到AOF文件,至于何时对AOF文件进行同步,则由操作系统控制。
从效率来说,no模式和everysec模式的效率差不多。
appendfsync选项的默认值是everysec,也推荐使用这个值,因为既保证了效率又保证了安全性。
3.2 载入AOF文件因为AOF文件包含了重建数据库所需的所有写命令,所以Redis服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原Redis服务器关闭之前的数据。
Redis读取AOF文件并还原数据库的详细步骤如下:
创建一个不带网络连接的伪客户端
因为Redis的命令只能在客户端上下文中执行,而载入AOF文件时所使用的命令直接来源于AOF文件而不是网络连接,所以服务器使用了一个没有网络连接的伪客户端来执行AOF文件保存的写命令。
伪客户端执行命令的效果和带网络连接的客户端执行命令的效果完全一样。
从AOF文件中分析并读取出一条写命令。
使用伪客户端执行被读取出的写命令。
一直执行步骤2和步骤3,直到AOF文件中的所有写命令都被执行完毕。
以上步骤如下图所示:
如果Redis服务器开启了AOF持久化功能,那么Redis服务器在启动时会载入AOF文件,
启动日志如下所示:
3.3 AOF重写因为AOF持久化是通过保存被执行的写命令来记录数据库数据的,所以随着Redis服务器运行时间的增加,AOF文件中的内容会越来越多,文件的体积会越来越大,如果不做控制,会有以下2点坏处:
过多的占用服务器磁盘空间,可能会对Redis服务器甚至整个宿主计算机造成影响。
AOF文件的体积越大,使用AOF文件来进行数据库还原所需的时间就越多。
举个例子,在客户端执行如下命令:
为了记录这个list键的状态,AOF文件就需要保存上面执行的6条命令。