Redis 持久化

🚀 Redis 持久化总体机制(记住一句话)

Redis 是内存数据库,但支持把内存快照或命令日志写到磁盘,防止宕机掉数据。
持久化依赖 RDB + AOF 两种策略,可单独用,也可混合使用。


1️⃣ RDB(快照)持久化

核心思想:把某一时刻的数据拍一个“全量快照”写入磁盘(dump.rdb)。

✅ 原理(重点)

⭐ 通过 Fork 子进程 执行快照逻辑

Redis 主进程执行 fork,复制出一个子进程:

  • 主进程继续处理请求(不阻塞)
  • 子进程负责把内存数据写入磁盘

读写分离,让持久化不影响主线程。

⭐ 写数据流程

  1. 主进程执行 fork()
  2. 子进程遍历内存所有 key
  3. 将数据序列化为 RDB 格式
  4. 顺序写入 dump.rdb 文件
  5. 写完后替换旧文件

RDB 文件很小,写入速度快。


🧠 RDB 触发时机

自动触发(配置)

save 900 1      # 900 秒内至少 1 次修改
save 300 10
save 60 10000

手动触发

  • SAVE(阻塞主线程,不推荐)
  • BGSAVE(后台子进程执行)

🌟 RDB 优点

  • 文件小,恢复速度快
  • fork + 子进程写,主线程几乎不受影响
  • 适合 定时备份全量迁移

🌧️ RDB 缺点

  • 可能丢失最近 N 秒的数据
  • 快照之间的数据变更无法记录。

2️⃣ AOF(Append Only File)持久化

记录每条写操作命令,重启时重放命令恢复数据。


🔥 AOF 原理(核心四步)

① 写命令追加到 AOF 缓冲区

Redis 主线程执行写命令后,会把命令转为文本写入:
appendonly.aof buffer

② 按策略写入 OS 缓冲区(write)

AOF 不立即落盘,而是根据策略执行 flush:

AOF fsync 策略(面试必问)

appendfsync always     # 每次写都 fsync(最安全最慢)
appendfsync everysec   # 每秒 fsync 一次(默认,丢 1 秒)
appendfsync no         # OS 决定(性能最好,风险最大)

③ AOF 文件不断增长 → 重写(rewrite)

为了避免 AOF 文件过大,Redis 会触发自动重写:

重写不是全量复制旧 AOF,而是根据当前内存,写出“最简命令集”。

例如:

INCR x
INCR x
INCR x
SET x 3

重写后只有:

SET x 3

重写也是 fork 子进程执行,不阻塞主线程。

④ 新旧 AOF 合并

重写完后:

  • 子进程生成 new.aof

  • 主线程接管:

    • 把重写期间的新命令追加进去
    • 替换旧 AOF

🌟 AOF 优点

  • 数据最完整(每秒 fsync 只丢 1 秒)
  • 命令文本可读,可直接编辑修复

🌧️ AOF 缺点

  • 文件比 RDB 大 5~10 倍
  • 恢复速度慢(需要重放)
  • 依赖 fsync,性能不如 RDB 稳定

3️⃣ 混合持久化(Redis 4.0+)

使用 RDB 存储“全量”,再在文件尾部追加 AOF 日志。

⭐ 原理

  • 重写时生成 RDB 内容写入 AOF
  • 后面再追加增量 AOF 命令

⭐ 优点

  • 恢复速度快(RDB 部分)
  • 数据更完整(AOF 部分)

⭐ 缺点

  • 文件比 RDB 大
  • 格式复杂,不如纯 RDB 简洁

4️⃣ 持久化崩溃恢复流程(你必须讲得出来)

重启 Redis 时:

如果开启 AOF:

  1. 如果 appendonly.aof 存在 → 优先加载 AOF
  2. 依次重放 AOF 命令
  3. 重建内存

否则:

  1. 加载 dump.rdb
  2. 恢复内存

优先 AOF 是因为它更完整。


5️⃣ RDB vs AOF(核心对比总结)

项目 RDB AOF
内容 内存快照 写命令日志
性能 中等
数据安全 丢较多 最安全
恢复速度
文件大小
使用场景 冷备、容灾 日志、增量恢复

👉 生产一般搭配使用:RDB + AOF everysec


6️⃣ 典型生产配置(复制黏过来就能用)

# 开启 AOF
appendonly yes
appendfsync everysec

# 开启 RDB
save 900 1
save 300 10
save 60 10000

# AOF 重写配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

7️⃣ 面试高频问题

Q:Redis 为什么要用 fork?
A:为了让持久化在子进程执行,主线程不阻塞。Redis 单线程架构必须通过 fork 实现“后台写盘”。

Q:fork 会阻塞吗?
A:会短暂阻塞(复制页表)。数据越大阻塞越明显。

Q:AOF 重写是否阻塞?
A:重写在子进程执行,不阻塞主线程。主线程只有“把增量写入新 AOF”那一瞬间轻微阻塞。

Q:Redis 崩溃后如何恢复?
A:优先加载 AOF > 若无 AOF 则加载 RDB。

posted @ 2025-12-05 15:05  中登程序猿  阅读(0)  评论(0)    收藏  举报