Redis 的 AOF

Redis 的 AOF(Append Only File,仅追加文件)持久化的运行机制,简单来说:AOF 通过记录 Redis 执行的所有写命令 **(如 SET、HSET、LPUSH 等)到文本日志文件中,Redis 重启时,会逐行重放 AOF 文件中的命令,从而恢复内存数据 **。与 RDB 的 "快照式" 持久化不同,AOF 是 "命令式" 的持久化,能最大程度保证数据不丢失,下面从核心运行流程、同步策略、重写机制、恢复流程、配置等方面详细拆解。

一、AOF 的核心运行流程

AOF 的工作分为三个核心阶段 ,整个流程围绕 "减少磁盘 IO 开销、保证数据安全性" 设计,具体如下:

1. 阶段 1:命令追加(Append)
  • 当客户端发送写命令(只读命令如 GET 不会记录)时,Redis 先执行命令,更新内存中的数据;

  • 然后将该命令的协议格式字符串追加到 **AOF 缓冲区(aof_buf)** 中(而非直接写入磁盘)。

    为什么用缓冲区?如果每次写命令都直接写入磁盘,频繁的磁盘 IO 会严重降低 Redis 性能,缓冲区可以批量写入,减少 IO 次数。

    示例:执行SET name tom,AOF 缓冲区会追加类似这样的协议字符串:

    bash 复制代码
    *3\r\n$3\r\nSET\r\n$4\r\nname\r\n$3\r\ntom\r\n

    (Redis 的 RESP 协议格式,包含命令参数数量、参数长度、参数内容,确保命令可重放)

2. 阶段 2:文件写入(Write)与同步(Sync)

Redis 会根据配置的AOF 同步策略 ,将 AOF 缓冲区中的数据写入(write)到 AOF 文件的内核缓冲区,再同步(fsync)到磁盘。

  • 写入(write):将数据从用户态缓冲区(aof_buf)写入内核态缓冲区(操作系统的页缓存),这一步是内存操作,速度快;
  • 同步(sync,即 fsync 系统调用):将内核缓冲区的数据强制刷入磁盘,这一步是磁盘 IO 操作,速度慢。

关键:AOF 的同步策略决定了数据安全性和性能的平衡,这是 AOF 运行的核心配置。

二、AOF 的同步策略(核心配置)

Redis 提供了三种 AOF 同步策略,通过redis.conf中的appendfsync参数配置,不同策略对应不同的数据安全性和性能开销:

同步策略 配置值appendfsync 执行逻辑 数据安全性 性能开销 适用场景
总是同步 always 每次写命令追加到缓冲区后,立即执行fsync,将数据刷入磁盘 最高(仅丢失故障瞬间的命令) 最大(频繁磁盘 IO,Redis 性能下降) 金融交易等对数据安全性要求极高的场景
每秒同步 everysec(默认) 每秒执行一次fsync,将缓冲区中的数据刷入磁盘(异步执行) 较高(最多丢失 1 秒数据) 适中(平衡性能与安全) 绝大多数生产环境场景
不主动同步 no Redis 仅负责将数据写入内核缓冲区,由操作系统决定何时fsync刷入磁盘(通常 30 秒) 最低(可能丢失大量数据) 最低(Redis 性能最优) 测试环境、对数据丢失不敏感的场景

注意:everysec是默认且推荐的策略,它在性能和数据安全性之间做了最优平衡 ------ 即使fsync阻塞,也只会阻塞异步线程,不会影响 Redis 主进程处理请求。

三、AOF 的重写机制(解决文件膨胀问题)

AOF 会不断追加写命令,随着时间推移,文件会变得越来越大(比如反复执行INCR counter,AOF 会记录所有 INCR 命令,而实际只需记录SET counter 1000即可)。为了解决这个问题,Redis 引入了 **AOF 重写(Rewrite)** 机制:

1. 重写的核心原理

AOF 重写不是对旧的 AOF 文件进行编辑或压缩,而是Redis 通过遍历当前内存中的数据,生成一组 "最简的写命令"(相当于重建数据的命令集),替换旧的 AOF 文件

  • 示例:内存中有counter=1000,旧 AOF 记录了 1000 次INCR counter,重写后只记录SET counter 1000,文件体积大幅缩小。
2. 重写的触发方式

分为手动触发自动触发两种:

(1)手动触发:BGREWRITEAOF命令(推荐)
bash 复制代码
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started  # 后台重写已启动
  • 执行逻辑:Redis 主进程fork一个子进程,由子进程负责生成新的 AOF 文件,主进程继续处理客户端请求(期间新的写命令会同时追加到旧 AOF 文件和AOF 重写缓冲区);
  • 子进程完成后,主进程会将重写缓冲区中的命令追加到新 AOF 文件,然后用新文件替换旧文件(原子操作)。
(2)自动触发:配置重写条件
bash 复制代码
# 当AOF文件大小增长超过指定百分比(默认100%,即翻倍)时触发重写
auto-aof-rewrite-percentage 100
# 触发重写的最小AOF文件大小(默认64MB,避免小文件频繁重写)
auto-aof-rewrite-min-size 64mb
  • 示例:如果当前 AOF 文件是 64MB,当文件增长到 128MB(翻倍)时,自动触发重写。
3. 重写的优势
  • 减小 AOF 文件体积,节省磁盘空间;
  • 重放命令时,执行的命令数更少,数据恢复速度更快。

四、AOF 的数据恢复流程

当 Redis 重启时,会优先加载 AOF 文件(如果 AOF 开启)恢复数据,流程如下:

  1. Redis 启动时,检查是否开启 AOF(appendonly yes);
  2. 如果开启,查找appendfilename指定的 AOF 文件(默认appendonly.aof);
  3. 如果文件存在,Redis 逐行读取并执行 AOF 文件中的写命令,将数据恢复到内存;
  4. 如果文件不存在或 AOF 未开启,才会加载 RDB 文件(如果有);
  5. 加载完成后,Redis 开始接受客户端请求。
异常处理:AOF 文件损坏

如果 Redis 异常关闭(如断电),可能导致 AOF 文件末尾的命令不完整,Redis 启动时会报错。此时可使用 Redis 提供的redis-check-aof工具修复:

bash 复制代码
# 修复AOF文件(会删除末尾不完整的命令)
redis-check-aof --fix /var/lib/redis/appendonly.aof

五、AOF 的核心配置(redis.conf)

除了上述的同步策略和重写配置,AOF 还有以下关键配置:

bash 复制代码
# 开启AOF持久化(默认no,需手动改为yes)
appendonly yes

# 指定AOF文件名
appendfilename "appendonly.aof"

# 指定AOF文件的保存目录(与RDB的dir配置相同)
dir /var/lib/redis

# AOF同步策略(默认everysec)
appendfsync everysec

# 重写期间是否暂停同步AOF(默认no,保证数据安全性)
no-appendfsync-on-rewrite no

# 开启AOF与RDB混合持久化(Redis 4.0+支持,推荐开启)
aof-use-rdb-preamble yes

混合持久化(aof-use-rdb-preamble yes):AOF 文件的开头是 RDB 的快照数据,后续是增量的 AOF 命令。这样既拥有 RDB 的快速恢复速度,又拥有 AOF 的实时数据安全性。

六、AOF 与 RDB 的核心对比(补充)

特性 AOF RDB
持久化方式 记录写命令(追加式) 记录内存快照(全量式)
数据安全性 高(最多丢失 1 秒数据,always 策略无丢失) 低(周期性快照,丢失快照间数据)
文件体积 大(命令追加,重写后缩小) 小(二进制压缩)
恢复速度 较慢(重放大量命令) 较快(直接加载快照)
性能开销 较低(缓冲区 + 异步同步) 较高(fork 子进程,大内存 fork 卡顿)

总结

关键点回顾

  1. AOF 的核心运行逻辑:写命令→追加到 AOF 缓冲区→根据同步策略写入 / 同步到 AOF 文件→重写机制压缩文件→重启时重放命令恢复数据。
  2. 同步策略 :有always(最安全)、everysec(默认推荐)、no(最快)三种,平衡数据安全与性能。
  3. 重写机制 :通过BGREWRITEAOF(手动)或配置条件(自动)触发,生成最简命令集的新 AOF 文件,解决文件膨胀问题。
  4. 数据恢复 :Redis 启动时优先加载 AOF 文件,文件损坏可通过redis-check-aof修复。
  5. 生产环境推荐 :开启 AOF+RDB 混合持久化(aof-use-rdb-preamble yes),兼顾恢复速度和数据安全性。

简单来说,AOF 的运行是 "记录命令→同步文件→压缩文件→重放恢复" 的闭环,是 Redis 保证数据高可用性的核心机制之一。

相关推荐
吃喝不愁霸王餐APP开发者2 小时前
Java后端系统对接第三方外卖API时的幂等性设计与重试策略实践
java·开发语言
TG:@yunlaoda360 云老大2 小时前
如何在华为云国际站代理商控制台进行SFS Turbo的性能与容量核查?
服务器·网络·数据库·华为云
TG:@yunlaoda360 云老大2 小时前
华为云国际站代理商的CBR主要有什么作用呢?
java·网络·华为云
ytttr8732 小时前
MATLAB基于LDA的人脸识别算法实现(ORL数据库)
数据库·算法·matlab
速易达网络3 小时前
基于Java TCP 聊天室
java·开发语言·tcp/ip
云老大TG:@yunlaoda3603 小时前
如何进行华为云国际站代理商跨Region适配?
大数据·数据库·华为云·负载均衡
沿着路走到底3 小时前
JS事件循环
java·前端·javascript
思成不止于此3 小时前
【MySQL 零基础入门】事务精讲(二):ACID 特性与并发问题
数据库·笔记·学习·mysql
Boilermaker19923 小时前
[MySQL] 初识 MySQL 与 SQL 基础
数据库·mysql