Java 面试题

Redis持久化:RDB和AOF深度对比

"Redis的持久化机制RDB和AOF有什么区别?生产上怎么选?"

为什么面试官会问这道题

持久化是Redis面试的第二高频题,仅次于单线程模型。考察你对"性能和数据安全"这个取舍的理解,以及有没有真正在线上运维过Redis——恢复时长、数据丢失容忍度、fork抖动,都是实战中真实踩过的坑。

如何回答

  1. 1

    先说两种模式:RDB是某一时刻的二进制快照,AOF是把每条写命令追加到日志文件,重启时重放还原。

  2. 2

    讲清RDB:SAVE阻塞主线程,BGSAVE会fork子进程。子进程通过写时复制(COW)共享父进程内存,父进程继续服务请求。文件紧凑、恢复快,但两次快照之间的数据崩溃就丢了。

  3. 3

    讲清AOF:每条写命令追加到磁盘,fsync策略三档——always(每条都刷,最安全最慢)、everysec(默认,最多丢1秒)、no(交给操作系统)。文件会越写越大,靠AOF重写压缩——重放当前数据集生成最小日志。

  4. 4

    说混合持久化(Redis 4+):AOF重写时先写一份RDB格式的快照做前缀,再追加增量AOF命令。恢复快、数据丢失少,两全其美。

  5. 5

    强调fork的代价:BGSAVE和AOF重写都要fork,几十GB的实例fork本身就要几百毫秒,期间Redis是卡住的。开了透明大页(THP)会更惨。

参考回答示例

Redis提供两种持久化。RDB是时间点快照——Redis fork一个子进程,子进程把整个数据集序列化成紧凑的二进制.rdb文件。靠写时复制(COW),父进程继续处理请求,只有被修改过的内存页才会真的复制,所以快照是一致的。RDB文件小,重启直接加载,恢复飞快。缺点是数据安全——两次快照之间宕机就全丢了。AOF把每条写命令追加写磁盘,关键参数是appendfsync:always每条都fsync,最安全但写吞吐会掉一个数量级;everysec是生产默认,最多丢1秒数据;no完全交给操作系统的pdflush。AOF文件会不断膨胀,Redis会定期触发AOF重写——基于当前内存状态生成最精简的命令序列,再原子替换旧文件。Redis 4开始有混合持久化——重写后的AOF文件头是一份RDB快照,后面接增量的AOF命令。加载时先用RDB快速载入,再重放少量增量命令。生产环境我一定开混合持久化,这是目前最优方案。运维上最大的坑是fork抖动。30GB的实例一次fork,光复制页表就要200-500毫秒,这期间Redis会卡住。解决方案:关闭透明大页(THP)、盯住latest_fork_usec指标、避开流量高峰做BGSAVE、或者做主从分离——从节点负责持久化,主节点只服务业务。

实用技巧

  • 一定要提写时复制(COW),这是BGSAVE能后台跑不影响业务的底层机制。

  • appendfsync三个选项的数据丢失边界要能精确说出来。

  • 中高级岗要能讲fork抖动和关THP的运维经验,这是加分项。

  • 面试官经常追问"你线上怎么配的为什么",提前准备一个具体案例,或者用即答侠实时给你提示框架。

常见问题

AOF文件损坏了怎么办?

用redis-check-aof --fix工具修复,会截断最后一条不完整的命令。损坏点之后的数据会丢失。

可以完全关闭持久化吗?

可以,save "" + appendonly no。纯缓存场景常用,挂了就从数据库重建。

开启持久化会影响写性能吗?

RDB几乎不影响主流程(在子进程做)。AOF的always档会显著拖慢写入,生产推荐everysec。

面试时担心忘词?即答侠实时助你

即答侠 AI 实时监听面试对话,自动识别问题并即时生成回答建议——无感辅助,让你从容应对每一道题。

免费试用即答侠