Redis 持久化详解:RDB 与 AOF 的配置、触发机制和实际测试


什么是持久化?

就是 Redis 将内存数据持久化到硬盘,避免从数据库恢复数据。之所以避免从数据库恢复数据是因为后端数据通常有性能瓶颈,大量数据从数据库恢复可能会给数据库造成巨大压力。

Redis 持久化通常有 RDB 和 AOF 两种方式,RDB 相当于快照备份,AOF 相当于追加形式的备份。

Redis 重启的时候,恢复数据的优先级 RDB > AOFAOF 恢复的优先级 appendonly.aof.{x}.base.rdb>appendonly.aof.{x}.incr.aof

一、RDB

1.1、什么是 RDB?

RDB 是 Redis DataBase 的缩写,RDB 就是将当前进程数据生成的快照保存到磁盘(相当于某一时刻的快照),因此磁盘中的值 <= 内存中的值。

1.2、RDB 怎么配置?怎么用?

触发 RDB 分为手动触发和自动触发两方式。

手动触发

手动触发有 save 和 bgsave 两个方式的命令

  • save 命令:阻塞当前 Redis 服务器,直到 RDB 操作完成为止。如果 Redis 中数据比较多,会造成长时间的阻塞,线上不建议使用此命令。此命令通常主动执行 save 命令或者手动停止重启 redis 服务的时候触发。
  • bgsave 命令:Redis 进程执行 fork 操作创建子进程,RDB 的持久化由子进程负责,完成后自动结束。阻塞只会发生在 fork 阶段,时间通常很短。此命令通常在 redis.conf 中配置 save m n 触发。

bgsave 流程如下

  1. Redis 客户端执行 bgsave 命令或者自动触发 bgsave 命令。
  2. 主进程判断当前是否存在正在执行的子进程,如果存在,主进程直接返回。
  3. 如果不存在正在执行的子进程,fork 一个新的子进程进行持久化数据,fork 过程是阻塞的,fork 操作完以后,主进程去执行其他操作。
  4. 子进程先将数据写入到临时的 rdb 文件中,待快照数据写入完成以后,替换旧的 rdb 文件。
  5. 同时子进程发送信号给主进程,通知主进程 rdb 持久化完成,主进程更新相关的统计信息。
graph TD
    A[开始] -->|执行 bgsave 命令| B(判断是否存在执行的子进程)
    B -->|存在| C[主进程直接返回]
    B -->|不存在| D[fork 新的子进程]
    D -->|fork 完成| E[主进程继续其他操作]
    D -->|写入数据到临时 RDB| F[写入完成]
    F -->|替换旧的 RDB 文件| G[发送信号给主进程]
    G -->|主进程更新统计信息| H[结束]

image-20240126093433292

自动触发

在下面 4 种情况下会自动触发

  1. redis.conf 中配置 save m n,即在 m 秒中有 n 次修改,自动触发 bgsave 生成 rdb 文件。
  2. 主从复制的,从节点从主节点全量复制的时候。
  3. 执行 debug reload 命令的时候。
  4. 执行 shutdown 命令的时候。

关闭 RDB 持久化 redis.config 文件中设置 save "" 就会关闭 redis 的 rdb 持久化(redis.config 文件更改以后,需要重启 redis,redis 的配置才会生效),除非手动执行 save/bgsave 命令,否则 redis 不会进行 rdb 操作。

1.3、实际测试

  1. 停止 redis,redis 自动执行 save 命令,保存数据。

image-20240126093449994

image-20240126093513231

  1. 通过几秒内几个键更改,自动 rdb。

image-20240126093529789

image-20240126093545586

image-20240126093601073

二、AOF

2.1、什么是 AOF?

AOF 是 Redis 以追加形式备份 Redis 数据的一种方式。

AOF 持久化的工作机制:

  1. 当 Redis 执行了一个写命令(SET、LPUSH、SADD)时,它会将该命令以文本协议的形式追加导 AOF 文件的末尾。
  2. 为了保证 Redis 在发生故障的时候,数据也不会丢失,Redis 会不断地将这些命令写入硬盘。
  3. 当 Redis 重启的时候,它会读取 AOF 文件中所有的命令并重新执行它们,一次来回复数据。

AOF 的三种同步频率:

  1. always:每个 Redis 写命令都会立刻同步到 AOF 文件中,这种模式提供了非常高的数据安全性,但是由于每次写入都需要进行磁盘 IO,性能可能会受到影响。
  2. everysec(默认配置):每秒钟同步一次,这种模式下,如果发生故障,最多丢失一秒钟的数据。这通常是一种很好的这种方案,提供了良好的性能和合理的数据安全性。
  3. no:由操作系统决定何时进行同步,这种模式可能会导致数据的丢失,因为在发生故障时,系统可能还没有来的及将数据写入磁盘。

AOF 文件的重写(压缩):

随着时间的推移,AOF 文件可能会变得非常大,因为每次写操作都会追加到文件中。Redis 提供了 AOF 重写的功能,这个过程可以创建一个新的 AOF 文件,文件中只包含了恢复当前数据状态所需要的最小命令集。这样可以减少磁盘的占用空间,并提高 Redis 的恢复速度。

Redis 的 AOF 重写是一个后台操作,它不会阻塞主 Redis 进程。在重写的过程中,对数据库的新写入会同时记录在旧的 AOF 文件和一个重写缓冲区中。当新的 AOF 文件准备好后,Redis 会将重写缓冲区中的所有命令追加到新的 AOF 文件中,并进行原子的替换旧的 AOF 文件。

AOF 持久化对应的文件:

image-20240126093616128

2.2、AOF 怎么配置?怎么用?

在 Redis 的配置文件(通常是 redis.conf)中,可以通过以下配置启用 AOF 持久化:

appendonly yes

重写 aof 文件的命令(压缩)

bgrewriteaof

然后根据需要设置 AOF 的同步频率

appendfsync everysec

还可以配置自动重写的触发条件

当 AOF 文件增长到原始大小的 100% (翻倍)时,且文件至少有 64MB 时,Redis 会自动触发重写过程。

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

2.3、实际测试

开启 aof 持久化

image-20240126093633496

设置 aof备份的频率

image-20240126093652256

查看 aof 的日志文件

image-20240126093825424

测试压缩后的 aof 文件

image-20240126093724832

最后

我是 xiucai,一位后端开发工程师。

如果你对我感兴趣,请移步我的个人博客,进一步了解。

- 文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊

- 本文首发于个人博客,未经许可禁止转载💌


文章作者: zhangxiulin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 zhangxiulin !
  目录