Redis 的 AOF 日志简介

316 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。


AOF 简介

AOF(Append Only File)日志是 Redis 的持久化方案之一,简而言之,就是将每一个数据操作的步骤以文本的形式保存在磁盘中,实现数据的持久化。

Redis 的 AOF 日志采用了限制性数据操作,再记录日志的形式。相较于川荣数据库先记录日志再执行操作。Redis 这种「后记」日志可以免去记录日志前的语法检查,如果语法错误,执行操作时就会报错。

但是,这样也存在风险,如果执行完一个命令还没有来得及记日志就宕机了,那么这条数据就有丢失的风险。

数据落盘

由于 AOF 日志是在执行操作后写入的,因此它不会造成当前操作的阻塞,但是,日志写入也是在主线程中执行的,因此如果磁盘写压力大的话,会导致日志记录缓慢,进而影响后续的操作。这时候就需要控制 AOF 日志写入磁盘的时机,Redis 提供了三个选项:

  • always(同步写入):每个命令执行完,都立刻将日志同步写入磁盘。
  • Everysec(每秒写入):每个命令执行完之后,先把日志写入到 AOF 内存缓冲区,每隔一秒钟把缓冲区的内容写入磁盘。
  • no(由操作系统控制):每个命令执行完之后,先把日志写入到 AOF 内存缓冲区,由操作系统控制什么时候写入磁盘。

从上面的介绍可以看出,每一个策略都不能再满足效率的同时又满足安全的需求,需要根据具体的使用场景进行权衡。

日志重写

随着日志文件的不断变大,会带来一些问题。比如写入效率降低、故障恢复缓慢等。为了应对这个问题,Redis 提供了 AOF 重写机制。

重写机制是指,基于当前的数据,创建一个新的 AOF 文件,将当前所有数据,每一个键值对用一条命令写入新的 AOF 文件中,以减少文件的体积。这样,对一个 key 的多次操作,就会在新的日志文件中变成一个单一的指令。

AOF 重写是一个漫长的过程,因此 Redis 会创建一个后台子进程 bgrewriteaof 来完成,以避免主线程的阻塞。具体过程如下:

首先,在执行重写开始的时候,主线程会 fork 出 bgrewriteaof 子进程,子进程会获得一份主进程的内存拷贝,包含当前数据库中的最新数据。

然后,bgrewriteaof 子进程在不影响主进程处理数据操作的情况下,把所有数据重新写入新的日志。

在 AOF 重写的过程中,主线程还在不断地进行数据处理操作。此时,在数据操作执行完之后,除了向 AOF 缓冲区记录日志之外,还会向 AOF 重写缓冲区写入日志。当所有的数据记录被重写完成后,重写缓冲区的操作也会写入新的 AOF 文件。当所有的操作都写入新的 AOF 日志中之后,日志重写就完成了。