Redis持久化:RDB与AOF原理、机制、用途、优缺点、混合持久化
Redis默认是内存数据库,数据断电即失。持久化就是把内存数据写入磁盘,保证宕机数据不丢失。Redis 提供两种核心持久化方案:RDB快照、AOF日志,以及 Redis4.0+ 推出的 RDB+AOF 混合持久化。
一、核心总览(面试第一句)
- RDB:快照持久化,保存「某一时刻的完整数据」,快、文件小、丢数据多
- AOF:日志持久化,保存「所有写入命令」,慢、文件大、几乎不丢数据
二、RDB 持久化原理(Redis Database Backup)
1. 原理
核心机制:在指定时间节点,fork子进程,把当前内存中所有数据一次性快照写入 dump.rdb 二进制文件。
属于全量持久化:保存的是数据结果,不是命令。
2. 触发方式
(1)自动触发(配置规则)
redis.conf 默认规则:
- save 900 1:900秒内至少1个key修改,触发快照
- save 300 10:300秒内至少10个key修改
- save 60 10000:60秒内至少10000个key修改
(2)手动触发
- bgsave:后台保存(fork子进程,不阻塞主线程,生产常用)
- save:前台保存(阻塞主线程,大数据量卡死,禁止线上用)
(3)停机触发
执行 shutdown 正常关闭Redis,会自动执行一次 bgsave。
3. 核心流程(BGSAVE)
- 主线程判断满足快照条件
- 调用fork() 创建子进程(短暂阻塞)
- 子进程遍历内存数据,写入临时rdb文件
- 写入完成替换旧rdb文件,结束
写时复制COW:fork后子进程共享内存,主线程新修改数据会复制新内存页,互不影响。
4. RDB 优点
- 文件体积小:二进制压缩快照,适合冷备份、迁移
- 恢复速度极快:直接加载数据,无需回放命令
- 性能开销低:子进程完成IO,主线程几乎无压力
5. RDB 缺点(致命)
- 丢失数据风险大:两次快照之间的数据完全不保存,宕机丢失区间数据
- fork耗时:超大内存实例fork子进程会短暂阻塞服务
- 无法秒级持久化:不能实时落地
三、AOF 持久化原理(Append Only File)
1. 原理
核心机制:记录Redis每一条写命令(set、hset、del等),以日志形式追加到 aof 文件。
重启Redis时,回放AOF日志命令恢复内存数据。属于增量持久化。
2. 三种刷盘策略(核心面试点)
AOF 真正决定丢不丢数据的关键:fsync刷盘策略
- appendfsync always:每写一条命令立刻刷盘,零丢失,性能极差
- appendfsync everysec(默认):每秒批量刷盘,最多丢失1秒数据,均衡方案
- appendfsync no:交给操作系统自动刷盘,性能最高,丢失数据最多
3. AOF 重写机制(核心原理+完整过程)
核心背景:AOF以日志形式逐条追加写命令,对同一个key的多次修改会留存大量冗余命令(如多次set覆盖、多次incr叠加),导致AOF文件体积持续膨胀、重启恢复耗时大幅增加。为此Redis提供**AOF重写(AOF Rewrite)**机制,精简日志、压缩文件体积。
核心本质:不读取旧的冗余AOF日志,直接遍历当前内存最新数据,生成一组可还原全量数据的最小化精简命令集,替换原有臃肿的AOF文件,彻底清除冗余指令。
(1)AOF重写触发条件
分为自动触发和手动触发两种,生产以自动触发为主:
- 手动触发:执行
bgrewriteaof命令,后台主动触发重写,不阻塞主线程 - 自动触发(配置控制):依靠两个核心参数判断:
1. auto-aof-rewrite-min-size:AOF文件最小重写阈值(默认64MB),文件小于该值不触发重写;
2. auto-aof-rewrite-percentage:文件增长率阈值(默认100%),即当前AOF文件大小相比上一次重写后增长1倍,且满足最小大小,自动触发重写。
(2)AOF重写完整执行流程(面试高频)
整体全程后台执行,仅短暂阻塞主线程,核心分为5步:
- 步骤1:触发重写,fork子进程
主线程判断满足重写条件,调用fork()创建专属重写子进程,仅fork瞬间短暂阻塞主线程,后续业务正常读写。 - 步骤2:子进程遍历内存,生成精简临时文件
子进程遍历Redis内存中所有key的最新状态,摒弃所有冗余命令,用最少的指令生成新的日志内容(例如多次修改同一个key,仅保留最终结果的一条set命令),写入aof_rewrite_temp临时文件。 - 步骤3:主线程缓存增量新命令(核心容错机制)
子进程重写期间,主线程正常处理用户的读写请求,新的写命令会同时追加到旧AOF文件和重写缓冲区。
目的:保证重写过程中新增数据不丢失,解决「重写期间数据更新无法录入新文件」的问题。 - 步骤4:子进程结束,主线程追加增量日志
子进程完成内存数据遍历,生成完整精简临时文件后退出;主线程将重写缓冲区中缓存的所有增量命令,追加到临时文件末尾,保证新旧数据完整、无遗漏。 - 步骤5:原子替换旧文件
通过系统原子操作,用精简的临时文件替换老旧臃肿的AOF文件,完成重写,后续持久化基于新文件执行。
(3)关键特性与资源优化点
- 无阻塞核心设计:重写核心逻辑由子进程完成,主线程仅承担缓存增量日志、收尾追加工作,几乎不影响业务读写性能;
- 规避日志空洞:缓冲区增量追加机制,彻底解决重写窗口期的数据丢失问题,保证数据一致性;
- 命令极致精简:对集合、哈希、数值自增等高频修改数据,统一合并为最终状态指令,文件压缩比极高。
(4)AOF重写注意事项
- 重写期间不会暂停AOF持久化,旧AOF文件持续写入,故障不会丢数据;
- fork子进程会消耗少量CPU和内存,大内存实例需规避业务高峰期重写;
- Redis允许同时存在RDB持久化和AOF重写,底层资源互斥,不会并发执行,避免资源耗尽。
问题:频繁修改同一个key,AOF会堆积大量冗余命令(多次set覆盖),文件越来越大。
AOF重写rewrite:根据当前内存最新数据,生成精简的最小命令集,替换旧日志。
不会读取旧日志,直接读内存数据,极大压缩文件体积。
问题:频繁修改同一个key,AOF会堆积大量冗余命令(多次set覆盖),文件越来越大。
AOF重写rewrite:根据当前内存最新数据,生成精简的最小命令集,替换旧日志。
不会读取旧日志,直接读内存数据,极大压缩文件体积。
4. AOF 优点
- 数据安全性极高:默认每秒刷盘,最多丢1秒数据
- 日志可读、可修复:文本格式,可手动删脏数据
- 增量写入:追加写,性能损耗小
5. AOF 缺点
- 文件体积大:命令日志远大于二进制快照
- 恢复慢:需要逐条回放命令
- 持续开销:高频写入场景IO压力比RDB大
四、RDB vs AOF 全方位对比(面试必背表)
| 对比维度 | RDB | AOF |
|---|---|---|
| 持久化形式 | 快照、保存数据结果(全量) | 日志、保存写入命令(增量) |
| 文件类型 | 二进制、体积小 | 文本日志、体积大 |
| 数据丢失 | 丢失两次快照间数据(多) | 最多丢失1秒数据(极少) |
| 恢复速度 | 极快 | 慢(回放命令) |
| 运行开销 | 低(周期性) | 较高(持续IO) |
| 可用性 | 适合冷备、迁移 | 适合线上高可靠业务 |
五、混合持久化(Redis4.0+ 终极方案)
1. 原理
混合持久化 = RDB快照 + AOF增量日志
AOF重写时:先将当前内存数据以RDB格式写入文件头部,后续增量命令以AOF格式追加。
2. 解决的痛点
- 纯AOF重启恢复太慢
- 纯RDB数据丢失太多
3. 优势
- 兼具 RDB恢复快 + AOF数据安全 双优点
- 文件体积小、重启速度大幅提升
- 线上生产最优配置
六、生产环境最佳实践(面试标准答案)
- 单机普通业务:开启混合持久化(默认开启),everysec刷盘
- 极高数据安全业务:AOF everysec + 定时RDB冷备
- 纯缓存、允许丢数据:关闭持久化,提升极致性能
- 禁止单独用纯RDB做线上持久化:丢失数据风险太高
七、极简面试背诵口诀
- RDB:定时快照、二进制、体积小、恢复快、丢数据多,适合备份迁移
- AOF:记录命令、日志追加、安全性高、最多丢1秒、文件大恢复慢
- 混合持久化:头RDB尾AOF,兼顾速度与安全,生产最优