💾 持久化
RDB 快照 · AOF 追加 · 混合持久化 · 丢失窗口分析 · 恢复流程
1. RDB 持久化的原理和触发方式?
RDB:把内存数据全量快照写入二进制文件 dump.rdb。恢复快、文件紧凑。
原理(fork + 写时复制):BGSAVE 时主进程 fork 子进程,子进程把内存写盘。fork 后父子共享内存页,主进程继续服务;父进程要修改某页时触发写时复制(COW)复制该页。所以:
- fork 瞬间有短暂阻塞(要复制页表,实例越大越慢)
- 快照期间大量写入 → 复制页多 → 内存和 IO 开销大
触发:手动 SAVE(同步阻塞,别用)/ BGSAVE(异步);自动配置 save 3600 1(900 秒内 ≥1 次变更即触发);主从全量复制时主库生成 RDB;正常关闭时。
RDB 配置
# 自动快照条件:任意满足即触发 BGSAVE
save 3600 1 # 900 秒内有 1 次写
save 300 100 # 300 秒内有 10 次写
save 60 10000 # 60 秒内有 1 万次写
stop-writes-on-bgsave-error yes # 快照失败时拒绝写(保数据安全)
rdbcompression yes
🎯 面试要点
- RDB 缺点:丢数据窗口——上次快照到故障间的所有写都丢(秒级~分钟级)
- fork 大实例会卡顿:单机内存别太大(经验 ≤ 10GB 左右),或用云 Redis
- RDB 适合:数据可容忍分钟级丢失、备份/灾难恢复(紧凑易传)
2. AOF 持久化的原理?三种刷盘策略?
AOF(Append Only File):记录每一条写命令(以 Redis 协议格式追加到 appendonly.aof)。恢复时重放命令。丢数据窗口小。
三种刷盘策略(appendfsync):
- always:每条命令都 fsync 磁盘。最安全,性能最差(秒级上万次 fsync)
- everysec(默认):每秒 fsync 一次。最多丢 1 秒数据,性能与安全平衡
- no:交给 OS 决定刷盘时机。最快,可能丢数秒数据
AOF 重写(Rewrite):AOF 无限增长 → 自动压缩:子进程把当前数据生成最小命令集(如 100 次 INCR 合并为一条 SET)。重写期间新命令进缓冲区,完成后追加。触发:aof_rewrite_min_size + 上次重写后增长比例(auto-aof-rewrite-percentage 100 默认翻倍触发)。
🎯 面试要点
- 恢复优先级:AOF 优先于 RDB(AOF 数据更全);启动时自动加载
- AOF 缺点:文件比 RDB 大、恢复比 RDB 慢(重放命令)
- aof-load-truncated yes:AOF 尾部损坏时截断加载,不拒绝启动(线上默认开)
3. 混合持久化?生产如何选择?
混合持久化(Redis 4.0,aof-use-rdb-preamble yes):AOF 重写时,前半段用 RDB 二进制格式(全量快照),后半段追加重写期间的增量命令。加载时:先加载 RDB 部分(快),再重放增量(数据全)。兼顾 RDB 的恢复速度和 AOF 的数据完整性,生产推荐。
选择建议:
- 纯缓存(可丢)→ 关持久化或 RDB
- 数据重要 → AOF everysec + 混合持久化 + 定期 RDB 备份
- 任何持久化都不如主从副本:持久化保"进程挂",副本保"机器挂"——两者都上
🎯 面试要点
- 面试延伸:Redis 作为数据库 vs 缓存的数据安全设计差异
- 备份策略:每天 RDB + 增量 AOF,异地存放,定期演练恢复