0%

Redis持久化


1. RDB(Redis Database Backup)工作流程

(1)触发机制

RDB 快照的生成可以通过以下几种方式触发:

  • 自动触发
    • 根据配置文件中的 save 指令触发。例如:
      1
      2
      3
      save 900 1       # 如果900秒内至少有1个键被修改,则触发快照
      save 300 10 # 如果300秒内至少有10个键被修改,则触发快照
      save 60 10000 # 如果60秒内至少有10000个键被修改,则触发快照
      当满足上述条件之一时,Redis 会自动触发一次快照操作。
    • 在 Redis 重启时,如果配置了 save 指令,Redis 会自动加载 .rdb 文件恢复数据。
  • 手动触发
    • 使用命令 SAVE:在主线程中同步生成快照,阻塞主线程,直到快照生成完成。
    • 使用命令 BGSAVE:在后台子进程中异步生成快照,不会阻塞主线程。

(2)快照生成过程

  1. 检查是否已经在生成快照
    • 如果当前正在执行 BGSAVEBGREWRITEAOF,Redis 会拒绝再次执行 BGSAVE,以避免同时运行多个子进程。
  2. 创建子进程
    • 如果执行的是 BGSAVE,Redis 会通过 fork() 创建一个子进程。子进程会继承父进程的数据空间,但不会阻塞父进程。
    • 在子进程中,Redis 会遍历内存中的所有数据,并将数据以 RDB 格式写入到一个临时文件中。
  3. 原子替换文件
    • 当子进程完成快照操作后,Redis 会将临时文件重命名为指定的 RDB 文件名(默认为 dump.rdb),并替换旧的快照文件。
    • 如果执行的是 SAVE,则直接在主线程中完成快照操作,阻塞主线程。

(3)恢复过程

  • 当 Redis 服务启动时,如果配置了 RDB 持久化,Redis 会自动加载 .rdb 文件。
  • Redis 会读取 RDB 文件,并将文件中的数据加载到内存中,恢复数据状态。
  • 如果同时使用了 AOF 持久化,RDB 文件会先被加载,然后应用 AOF 日志中的增量数据。

2. AOF(Append Only File)工作流程

(1)日志记录过程

  1. 配置 AOF 持久化
    • 在配置文件中设置 appendonly yes,启用 AOF 持久化。
    • 可以设置 appendfilename 来指定 AOF 文件的名称(默认为 appendonly.aof)。
  2. 记录写操作
    • 当 Redis 执行写操作(如 SETLPUSHINCR 等)时,会将这些命令以 Redis 命令协议的格式追加到 AOF 文件中。
    • AOF 文件是一个纯文本文件,记录了所有写操作的命令和参数。

(2)同步方式

AOF 提供了三种同步方式,控制写操作何时同步到磁盘:

  • **appendfsync always**:
    • 每次写操作都会立即同步到磁盘,数据安全性最高,但性能开销最大。
  • **appendfsync everysec**:
    • 每秒同步一次,兼顾性能和数据安全性。这是推荐的默认设置。
  • **appendfsync no**:
    • 由操作系统决定何时同步到磁盘,性能最好,但数据丢失风险最高。

(3)日志重写(Rewrite)

  • 背景:随着时间推移,AOF 文件会变得越来越大,因为每个写操作都会被追加到文件中。为了压缩文件大小,Redis 提供了日志重写机制。
  • 触发方式
    • 手动触发:使用命令 BGREWRITEAOF
    • 自动触发:根据配置文件中的 auto-aof-rewrite-percentageauto-aof-rewrite-min-size 参数自动触发。例如:
      1
      2
      auto-aof-rewrite-percentage 100
      auto-aof-rewrite-min-size 64mb
      表示当 AOF 文件大小超过上次重写后的大小的 100%,并且文件大小超过 64MB 时,自动触发 AOF 重写。
  • 重写过程
    1. Redis 通过 fork() 创建一个子进程。
    2. 子进程会读取当前内存中的数据,并以更紧凑的方式重新生成 AOF 文件。
    3. 在重写过程中,主进程会继续将新的写操作追加到临时 AOF 文件中。
    4. 当子进程完成重写后,Redis 会用新的 AOF 文件替换旧的 AOF 文件,并将临时文件中的增量数据追加到新的 AOF 文件中。

(4)恢复过程

  • 当 Redis 服务启动时,如果配置了 AOF 持久化,Redis 会自动加载 AOF 文件。
  • Redis 会从 AOF 文件的开头开始,逐条读取并执行文件中的命令,恢复数据状态。
  • 如果 AOF 文件在崩溃时被截断,可以使用 redis-check-aof 工具修复文件。

3. RDB 和 AOF 的结合使用

在实际生产环境中,通常会同时使用 RDB 和 AOF,以兼顾数据安全性和恢复速度:

  1. RDB 定期备份
    • 每隔一段时间(如每 15 分钟或每小时)生成一次 RDB 快照,用于快速恢复。
  2. AOF 作为增量备份
    • 在两次 RDB 快照之间,使用 AOF 记录增量数据,确保数据不会丢失。
  3. 恢复过程
    • 启动 Redis 时,先加载 RDB 快照,快速恢复大部分数据。
    • 然后应用 AOF 日志中的增量数据,确保数据的完整性。

4. 面试中的常见问题

问题 1:RDB 和 AOF 的区别是什么?

  • 回答
    • RDB 是快照持久化,定期生成内存数据的完整备份,文件紧凑,恢复速度快,但可能会丢失快照之间的数据。
    • AOF 是日志持久化,实时记录写操作命令,数据安全性高,最多只会丢失最后一次同步之后的数据,但文件体积大,恢复速度慢。

问题 2:如何解决 AOF 文件过大问题?

  • 回答
    • 使用 BGREWRITEAOF 手动触发日志重写。
    • 配置 auto-aof-rewrite-percentageauto-aof-rewrite-min-size 参数,让 Redis 自动触发日志重写。

问题 3:如果 Redis 同时使用 RDB 和 AOF,启动时会加载哪个文件?

  • 回答
    • 如果同时使用 RDB 和 AOF,Redis 会优先加载 AOF 文件。如果 AOF 文件不存在,则加载 RDB 文件。

问题 4:如何避免 RDB 快照对性能的影响?

  • 回答
    • 使用 BGSAVE 命令在后台生成快照,避免阻塞主线程。
    • 合理设置快照频率,避免过于频繁地生成快照。