Redis ①①-AOF

发布于:2025-06-23 ⋅ 阅读:(12) ⋅ 点赞:(0)

在这里插入图片描述

AOF 持久化

AOF(Append Only File,文件追加方式),与 RDB 不同,AOF 持久化记录的是客户端所有的操作命令,并以文本的格式追加到一个日志文件中,且 AOF 是实时记录的,而 RDB 是定期记录的。

这个操作有点类似于 MySQL 的 binlog。

AOF 默认是关闭状态,需要通过配置文件开启。找到配置文件的 appendonly 选项,设置为 yes 即可
appendfilename 则是日志文件的名称,默认是 appendonly.aof

开启 AOF 后,RDB 就不生效了,下次 Redis 重启后,会优先加载 AOF 文件。

AOF 是实时记录客户端的命令操作的,这是否会影响其性能?

  • 其实不然,AOF 并非是直接让工作进程把数据写入到硬盘,而是先写入到一个内存中的缓冲区(该缓冲区是 Redis 定义的),积累到一定容量后,再一次性写入到硬盘。
  • 写入到硬盘时,与该数据量的大小关系不大,主要还是和硬盘写入的次数有关。100KB 的数据,分 100 次写入,每次写入 1KB 和一次全部写入,效率是不一样的,明显是后者效率更高。
  • AOF 是通过追加的方式,将命令操作追加到日志文件中,所以是顺序写入的,这比随机写入要快很多。
    在这里插入图片描述

虽然缓冲区解决了实时写入到硬盘的性能问题,但该缓冲区本质还是在内存中的,如果 Redis 宕机,此时缓冲区的数据还没来得及写入到硬盘中,就会丢失。

Redis 提供了三个可配置项,用于改变缓冲区的刷新策略,该配置项在配置文件的 appendfsync 选项中:

  • always:命令写入 aof_buf 后调用 fsync 同步,完成后返回。刷新频率最高,数据可靠性最高,性能最低。
  • everysec:命令写入 aof_buf 后,每秒调用一次 fsync 同步,完成后返回。刷新频率较高,数据可靠性较高,性能较低。(默认为 everysec)
  • no:命令写入 aof_buf 后,又 OS 调用 fsync 同步。刷新频率最低,数据可靠性最低,性能最高。

重写机制

随着客户端操作命令的不断增多,AOF 文件也会越来越大,文件过大,就会影响下次 Redis 重启的速度。

Redis 提供了 重写机制,能够针对 AOF 文件进行优化,减少文件体积。
该优化就是将 AOF 文件里的命令操作进行整理,将那些冗余的命令操作合并成一个命令操作,或者直接将一批命令操作删除:

lpush k1 111
lpush k1 222
lpush k1 333

上述命令其实可以合并成一个命令操作:

lpush k1 111 222 333
set k1 111
set k1 222
del k1

上述命令的最终结果就是删除键 k1。所以这三条命令就可以直接删除了。

重写触发

  • 手动触发:调用 BGREWRITEAOF 命令。
  • 自动触发:根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 配置项确定自动触发的时机。
    • auto-aof-rewrite-min-size:AOF 文件大小达到该值时,自动触发重写。默认为 64MB。
    • auto-aof-rewrite-percentage:当前 AOF 占用大小相比较于上次重写时增加的比例。

重写流程
在这里插入图片描述

与 RDB 类似,AOF 重写的过程也是 fork 出一个子进程进行重写,重写的并不需要读取原来的 AOF 文件,然后进行优化整理什么的,而是直接基于当前父进程里的数据进行重写即可。

fork 出子进程后,其内存里的数据是父进程里的数据的拷贝,并不是共享的,而是独立的。

所以,如果在重写过程中,如果此时客户端也对父进程进行命令操作,然后父进程将该命令操作写入到 aof_buf,但是子进程却并不知道有新的命令操作,这就会导致数据的不一致性。

为了解决这个问题,Redis 又引入了一个 aof_rewrite_buf,也就是重写缓冲区,在执行重写时,父进程就会创建该缓冲区。

子进程在重写时,父进程新增加命令操作会写入到 aof_buf 以及 aof_rewrite_buf 中,子进程重写完后,会再将 aof_rewrite_buf 中的数据和之前写入的 AOF 文件同步,然后生成新的 AOF 文件,将旧的 AOF 文件替换。

尽管子进程会生成新的 AOF 文件,但是父进程还需要根据 aof_buf 将数据写入到旧的 AOF 文件,这是因为如果在重写过程中,Redis 宕机,那么此时新的 AOF 文件可能就写了一半,即数据是不完整的。

为了避免该情况的发生,旧文件就不能不写了,只有子进程彻底写完并且通过信号通知父进程后,才可以将新的 AOF 文件替换掉旧的 AOF 文件。

混合持久化

混合持久化是将 RDB 和 AOF 两种持久化方式的优点结合,在触发 AOF 重写时,先将当前内存的数据以 RDB 的二进制格式写入到 AOF 文件的开头,再将后续的操作命令以 AOF 的文本格式追加到文件末尾。

通过配置项里的 aof-use-rdb-preamble 选项,可以开启或关闭混合持久化,设置为 yes 开启,设置为 no 关闭。

如果 RDB 和 AOF 同时开启,Redis 启动时,会优先加载 AOF 文件,RDB 文件就被忽略了。

为 yes 开启,设置为 no 关闭。

如果 RDB 和 AOF 同时开启,Redis 启动时,会优先加载 AOF 文件,RDB 文件就被忽略了。
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到