Redis持久化:RDB与AOF原理、机制、用途、优缺点、混合持久化

约 4105 字

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)

  1. 主线程判断满足快照条件
  2. 调用fork() 创建子进程(短暂阻塞)
  3. 子进程遍历内存数据,写入临时rdb文件
  4. 写入完成替换旧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. 步骤1:触发重写,fork子进程
    主线程判断满足重写条件,调用fork()创建专属重写子进程,仅fork瞬间短暂阻塞主线程,后续业务正常读写。
  2. 步骤2:子进程遍历内存,生成精简临时文件
    子进程遍历Redis内存中所有key的最新状态,摒弃所有冗余命令,用最少的指令生成新的日志内容(例如多次修改同一个key,仅保留最终结果的一条set命令),写入aof_rewrite_temp临时文件。
  3. 步骤3:主线程缓存增量新命令(核心容错机制)
    子进程重写期间,主线程正常处理用户的读写请求,新的写命令会同时追加到旧AOF文件和重写缓冲区。
    目的:保证重写过程中新增数据不丢失,解决「重写期间数据更新无法录入新文件」的问题。
  4. 步骤4:子进程结束,主线程追加增量日志
    子进程完成内存数据遍历,生成完整精简临时文件后退出;主线程将重写缓冲区中缓存的所有增量命令,追加到临时文件末尾,保证新旧数据完整、无遗漏。
  5. 步骤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 全方位对比(面试必背表)

对比维度RDBAOF
持久化形式快照、保存数据结果(全量)日志、保存写入命令(增量)
文件类型二进制、体积小文本日志、体积大
数据丢失丢失两次快照间数据(多)最多丢失1秒数据(极少)
恢复速度极快慢(回放命令)
运行开销低(周期性)较高(持续IO)
可用性适合冷备、迁移适合线上高可靠业务

五、混合持久化(Redis4.0+ 终极方案)

1. 原理

混合持久化 = RDB快照 + AOF增量日志

AOF重写时:先将当前内存数据以RDB格式写入文件头部,后续增量命令以AOF格式追加。

2. 解决的痛点

  • 纯AOF重启恢复太慢
  • 纯RDB数据丢失太多

3. 优势

  • 兼具 RDB恢复快 + AOF数据安全 双优点
  • 文件体积小、重启速度大幅提升
  • 线上生产最优配置

六、生产环境最佳实践(面试标准答案)

  1. 单机普通业务:开启混合持久化(默认开启),everysec刷盘
  2. 极高数据安全业务:AOF everysec + 定时RDB冷备
  3. 纯缓存、允许丢数据:关闭持久化,提升极致性能
  4. 禁止单独用纯RDB做线上持久化:丢失数据风险太高

七、极简面试背诵口诀

  • RDB:定时快照、二进制、体积小、恢复快、丢数据多,适合备份迁移
  • AOF:记录命令、日志追加、安全性高、最多丢1秒、文件大恢复慢
  • 混合持久化:头RDB尾AOF,兼顾速度与安全,生产最优