# 面试题:AOF 和 RDB 是什么?AOF 持久化策略有哪三种?你们是怎么选的?AOF 什么时候重写?为什么重写? 这是一个非常常见、但回答质量能快速区分“使用 Redis 的工程师”和“真正懂 Redis 的架构师”的问题。 背景是: Redis 是内存数据库,靠 **AOF / RDB / 混合持久化** 保证数据不丢。 AOF 是“写命令日志”,RDB 是“全量快照”。 **问题核心:** 1. AOF、RDB 分别是什么?优缺点? 2. AOF 的三种持久化策略是哪三种? 3. 在真实线上,我们如何选择 AOF 策略? 4. AOF 为什么要重写?什么时候重写? 5. 重写机制的原理是什么? 下面逐条拆开。 --- ## 一、AOF 和 RDB 分别是什么? ### 1)RDB(Redis DataBase snapshot) **RDB 是 Redis 的“内存快照”,定时把所有数据写成一个 dump.rdb 文件。** 特性: * **全量数据**快照 * 由 `fork()` 子进程执行,不阻塞主线程 * 文件小、加载快 * 适合冷备、定期备份 * 可能丢失最近一次快照之后的数据(分钟级) 优点: * 恢复速度快 * 文件紧凑 * 对性能影响最小(主进程几乎无感知) 缺点: * **无法做到实时持久化** * 两次快照之间的数据可能丢失 --- ### 2)AOF(Append Only File) **AOF 是把每一条写命令都记录下来(类似 MySQL binlog)。** 特性: * 追加写日志,记录所有写操作 * 更高的数据安全性 * 可通过重写机制压缩日志体积 优点: * 数据更安全(可做到秒级持久化) * 日志可读、可审计 * 意外故障时恢复能力强 缺点: * 文件体积大 * 恢复较慢 * 写磁盘频率高(要选好策略) --- ## 二、AOF 持久化策略有哪三种? AOF 的落盘策略由 `appendfsync` 参数控制,共三种: ### 1)`appendfsync always`(每次写都 fsync) 特点: * **最安全** * **最慢**(磁盘频繁同步) * 每次写操作都要 fsync,性能下降巨大 适合: * 金融级别数据(极少这样用) * 写少读多且数据极重要 --- ### 2)`appendfsync everysec`(每秒 fsync 一次)【**最常用**】 特点: * Redis 主线程追加日志到 OS 缓存(非常快) * 后台每秒 fsync 一次(由单独线程负责) * 最多丢失 1 秒的数据 这是 **线上主流选择**,是性能与安全性的最佳平衡。 适合: * 电商、社交、推荐等对数据一致性要求较高但又对性能敏感的系统 --- ### 3)`appendfsync no`(不 fsync,只交给 OS) 特点: * **由操作系统决定何时 flush 到磁盘** * 性能最好 * 洪泛写的情况下可能丢失大量数据 适合: * 非关键数据(cache-only),不推荐生产用 --- ## 三、真实线上我们是怎么选的? 标准选择: > **99% 场景使用 `appendfsync everysec`。** 原因: * 性能极高,主线程无阻塞 * 最多丢 1 秒数据,能接受 * 不需要昂贵的 SSD IOPS 支撑(不像 always) 大型公司(美团、滴滴、字节)的 Redis 配置几乎都是: ``` appendonly yes appendfsync everysec ``` 特别关键的数据(资金类)会采用: * Redis 作为纯缓存,不持久化 * 或者搭配 **AOF + RDB 混合持久化**(Redis 7 强烈推荐) --- ## 四、AOF 重写(Rewrite)是什么?为什么要重写? ### 1)AOF 重写是什么? AOF 重写不是把旧日志压缩,而是: > **基于当前数据库数据状态,重新生成一份最小化的 AOF 文件。** 例如: 之前日志记录: ``` SET a 1 SET a 2 SET a 3 SADD set 1 SADD set 2 SADD set 3 ``` 重写后变成: ``` SET a 3 SADD set 1 2 3 ``` 这是一个基于当前存量数据重建最短命令序列的过程。 --- ### 2)AOF 为什么要重写? 原因很硬核: #### a)AOF 文件会越来越大 如果不重写,AOF 会无限膨胀,比如几十 GB,导致: * 恢复速度变慢 * 同步磁盘负担变重 * 容易影响主线程 #### b)重写后的 AOF 更短、更快恢复 AOF 重写后的文件通常比之前小几十倍。 #### c)重写不影响线上性能 重写由 **子进程执行**,不会阻塞主线程。 --- ## 五、AOF 什么时候重写? Redis 有自动重写机制,由参数控制: ``` auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb ``` 含义: 1. AOF 文件大小比上次重写时 **增长了 100%**(翻倍) 2. 且文件大小至少达到 **64MB** 就会触发自动重写。 你也可以手动触发: ``` bgrewriteaof ``` --- ## 六、面试总结话术 你可以这样回答: > “Redis 有两种持久化机制:**RDB 是全量快照,AOF 是写命令日志**。 > > AOF 有三种落盘策略:`always`、`everysec`、`no`。 > 我们线上使用的是 **everysec**,它能做到性能快、数据最多丢一秒,是大多数公司生产的选型。 > > AOF 会在文件膨胀到一定阈值后触发 **AOF 重写**,重写是由子进程基于当前内存数据生成一份最小化的 AOF 文件,避免文件无限增长、加快恢复速度。 > > 所以我们整体策略是: > **开启 AOF + everysec,定期 AOF rewrite,再配合 RDB 做冷备。**”