前面我们探究过RDB文件,这里我们也将对AOF文件进行探究,默认情况下,AOF的名字为appendonly.aof。下面我们使用FLUSHALL命令清空所有数据。

127.0.0.1:6379> FLUSHALL
OK

1、下面我们开启AOF持久化

127.0.0.1:6379> CONFIG SET appendonly yes
OK

现在redis中没有任何数据,所以appendonly.aof会是一个空文件

[root@localhost redis]# ll appendonly.aof 
-rw-r--r--. 1 root root 0 Aug 19 12:49 appendonly.aof

2、写入数据到redis并查看appendonly.aof文件内容

127.0.0.1:6379> set k1 v1
OK

查看文件内容

[root@localhost redis]# cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$2
v1
127.0.0.1:6379> INCR num
(integer) 1
127.0.0.1:6379> INCR num
(integer) 2

查看文件内容:

[root@localhost redis]# cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$2
v1
*2
$4
INCR
$3
num
*2
$4
INCR
$3
num
127.0.0.1:6379> SET k2 v2
OK

查看文件内容:

[root@localhost redis]# cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$2
v1
*2
$4
INCR
$3
num
*2
$4
INCR
$3
num
*3
$3
SET
$2
k2
$2
v2
127.0.0.1:6379> DEL k2
(integer) 1
127.0.0.1:6379> DEL k3
(integer) 0

查看文件内容:

[root@localhost redis]# cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$2
v1
*2
$4
INCR
$3
num
*2
$4
INCR
$3
num
*3
$3
SET
$2
k2
$2
v2
*2
$3
DEL
$2
k2

3、使用BGREWRITEAOF命令手动触发AOF重写

127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started

再次查看文件内容:

[root@localhost redis]# cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
SET
$2
k1
$2
v1
*3
$3
SET
$3
num
$1
2
工作原理

  从以上的操作可以看出,我们首先禁用了AOF持久化并使用FLUSHALL命令清空了Redis中的所有数据。清理后我们重新开启了AOF持久化功能,同时创建了一个空的AOF文件。在清理数据的时候,必须要禁用AOF,否则AOF文件里面会有数据并不是空文件。

  从我们每次执行增加、修改和删除命令后,同时去查看AOF文件,会发现文件内容中,首先出现SELECT命令,这里表示选择索引为0的数据库,REDIS支持的数据库从0到15的数字指定,默认是0;当我们操作一个命令,文件中就会记录该命令,当某个命令没有引起数据的改变的时候,该命令不会记录在AOF文件中,如上面删除的k3。

  从上面执行的命令可以看出,只要执行的每一个命令都会写入到AOF文件中,但是也看到了一些没用的命令还存在文件中,如k1,后面被删除了,还有就是num,执行了两次incr。这样的情形如果很多就会使得文件很大。在前面我们已经说过,我们可以使用AOF重写,执行BEREWRITEAOF命令来执行AOF重写。重写后我们再次查看AOF文件,发现k1相关信息不见了,num也被合并了,这样就减少了文件的大小。

  Redis主进程会创建一个子进程来执行AOF重写,这个子进程会创建一个新的AOF文件来存储重写的结果,以防止重写操作的时候失败影响旧的AOF文件。父进程则继续响应请求并将命令追加到旧的AOF文件中。在创建子进程是,由于使用了写时复制机制,所以子进程不会占用与父进程相同的数量的内存。但是由于写时复制机制的限制,子进程不能访问在其被创建后产生的新书记。Redis通过如下的方式来解决这个问题:子进程在创建后,父进程将接收到的命令写入一个命令aof_rewrite_buf_blocks的缓冲区。当子进程完成AOF文件的重写后,它会向父进程发送信号。父进程把aof_rewrite_buf_blocks缓冲区中的命令写入到新的AOF文件中,然后使用新的文件替换旧的AOF文件。

  前面我们使用了BGREWRITEAOF命令触发AOF重写,那么我们还可以使用Redis的配置自动的执行AOF重写。主要有两个参数来控制:

  • auto-aof-rewrite-min-size:如果文件大小小于该值则AOF重写不会被触发,默认值为64MB
  • auto-aof-rewrite-percentage:Redis将记录最后一次AOF重写操作的大小。如果当前的AOF文件的大小增长值超过了这个百分比,则触发一次重写。将该值设置为0将禁用自动AOF重写,默认为100.