Redis 在 AOF 重写期间是怎么保证数据一致性的?Redis 的 AOF 是如何实现“先写日志再写数据”的?
这两个问题属于 Redis AOF 的高级知识点,非常适合面试官用来考察你对“写入一致性”和“数据恢复安全性”的理解。我们逐个解析,非常系统地给你讲透 👇
✅ 第一个问题:
Redis 在 AOF 重写期间是怎么保证数据一致性的?
🔍 背景:什么是 AOF 重写?
-
AOF(Append Only File)会不断地变大,所以 Redis 会在合适的时机重写 AOF 文件(rewrite)
-
重写并不是简单地复制旧文件,而是重新构建一个最小化的、可以恢复当前数据状态的 AOF 文件
-
重写由后台子进程 bgrewriteaof 执行,不阻塞主线程
✅ 关键问题:那这期间主线程还在处理新的写命令,咋办?
这就涉及到 Redis 的“双写缓冲 + 日志对账机制”,下面是完整流程:
🚀 AOF 重写期间的一致性保障机制:
1️⃣ Fork 子进程创建临时文件(比如
temp-rewrite.aof
)
-
Redis 主进程会 fork 出一个子进程
-
子进程开始根据内存快照生成新的 AOF 文件
2️⃣ 主线程继续正常服务新命令
-
主线程继续把写操作写入原始的 AOF 缓冲区(旧 AOF 文件)
3️⃣ Redis 主进程
维护一个 AOF rewrite 缓冲区(diff buffer)
-
专门用来记录 AOF 重写期间新增的写命令(和原 AOF 不冲突)
4️⃣ 子进程重写完成,通知主线程
-
子进程完成后,把重写文件交给主线程
5️⃣ 主线程会把
diff buffer 的命令
也追加到新的重写文件中
6️⃣ 替换旧 AOF 文件
-
Redis 用新 AOF 文件替换原始文件(如重命名 temp-rewrite.aof → appendonly.aof)
✅ 所以:
主线程和重写子进程完全解耦,同时数据一致性也得到保证!
🎯 面试说法:
Redis 在 AOF 重写期间采用子进程异步构建新 AOF 文件,并使用主进程的 rewrite 缓冲区(diff buffer)记录期间新增的写命令,最后将这些命令追加到新文件末尾,从而保证数据的一致性和完整性。
✅ 第二个问题:
Redis 的 AOF 是如何实现“先写日志再写数据”的?
这是问你:Redis 是不是“Write-Ahead Logging(预写日志)”机制?答案是 ✅ 是的!
🔍 什么是“先写日志,再写数据”?
这个机制最核心的逻辑是:
所有的数据变更,必须先被记录在日志文件(AOF)中,写成功后才算数据操作完成。
🧱 Redis 是怎么做到的?
流程如下:
1. 客户端发起写操作(如 SET user Tom)
2. Redis 执行命令,修改内存数据(写入 dict)
3. 把这条命令写入 AOF 缓冲区
4. 根据 appendfsync 策略刷盘(同步 fsync 到磁盘)
5. 返回客户端“OK”
❗注意:只有在 AOF 写入成功后,Redis 才认为“这个命令成功”
✨ 为什么这么做?
-
如果先修改内存,没记录日志,断电会丢数据
-
所以必须确保日志写入成功,才能继续其他操作
-
这就是“先日志,后数据”的核心理念(虽然 Redis 是内存数据库,但依然采用这类机制来保证持久化的一致性)
✅ 小结一句话(适合面试口述):
Redis 的 AOF 使用了“预写日志”机制,即先把所有写操作记录到 AOF 缓冲区,再通过 fsync 写入磁盘,最后才返回操作结果。这确保了即使 Redis 崩溃,重启时也可以通过 AOF 文件恢复数据。
在 AOF 重写期间,Redis 使用了“diff 缓冲区”来记录新增命令,重写完后主线程把这些增量命令追加到新 AOF 文件末尾,最终以“主线程原子替换”的方式完成 AOF 切换,从而保证整个过程中数据的一致性和可靠性。
浙公网安备 33010602011771号