原理

6f0ab40396b7fc2c15e6f4487d3a0ad7.webp

AOF 默认不开启,需要修改配置文件:

0e2d081af084c41802c7b5de8aa41bd4.webp

为什么要先执行命令,再写入日志?

  1. 避免额外的检查开销

    如果先将写操作命令记录到 AOF 日志里,再执行该命令的话,如果当前的命令语法有问题,那么如果不进行命令语法检查,该错误的命令记录到 AOF 日志里后,Redis 在使用日志恢复数据时,就可能会出错。

    而如果先执行写操作命令再记录日志的话,只有在该命令执行成功后,才将命令记录到 AOF 日志里,这样就不用额外的检查开销,保证记录在 AOF 日志里的命令都是可执行并且正确的。

  2. 不会阻塞当前写操作命令的执行

    因为当写操作命令执行成功后,才会将命令记录到 AOF 日志。

风险

  1. 执行写操作命令和记录日志是两个过程,那当 Redis 在还没来得及将命令写入到硬盘时,服务器发生宕机了,这个数据就会有丢失的风险
  2. 由于写操作命令执行成功后才记录到 AOF 日志,所以不会阻塞当前写操作命令的执行,但是可能会给「下一个」命令带来阻塞风险

三种写回策略

Redis 写入 AOF 日志的过程,如下图:

https://cdn.xiaolincoding.com//mysql/other/4eeef4dd1bedd2ffe0b84d4eaa0dbdea.png

我先来具体说说:

  1. Redis 执行完写操作命令后,会将命令追加到 server.aof_buf 缓冲区
  2. 然后通过 write() 系统调用,将 aof_buf 缓冲区的数据写入到 AOF 文件,此时数据并没有写入到硬盘,而是拷贝到了内核缓冲区 page cache,等待内核将数据写入硬盘;
  3. 具体内核缓冲区的数据什么时候写入到硬盘,由内核决定。

Redis 提供了 3 种写回硬盘的策略,控制的就是上面说的第三步的过程。

在 redis.conf 配置文件中的 appendfsync 配置项可以有以下 3 种参数可填: