4.redis持久化(下)

73 阅读8分钟

4.3AOF 持久化

Append Only File,指 Redis 将每一次的写操作都以日志的形式记录到一个 AOF 文件中的持久化技术。当需要恢复内存数据时,将这些写操作重新执行一次,便会恢复到之前的内存数据状态。

4.3.1 AOF 基础配置

(1) AOF 的开启

默认情况下 AOF 持久化是没有开启的,通过修改配置文件中的 appendonly 属性为 yes 开启

(2) 文件名配置

Redis 7 在这里发生了重大变化。原来只有一个 appendonly.aof 文件,现在具有了三类多个文件:

  • 基本文件:全部数据的快照,可以是 RDB 格式也可以是 AOF 格式。该文件可以有多个。
  • 增量文件:以操作日志形式记录转为 AOF 后的写入操作。该文件可以有多个。
  • 清单文件:用于维护 AOF 文件的创建顺序,保障激活时的应用顺序。该文件只有一个。

(3) 混合式持久化开启

aof-use-rdb-preamble。默认值为 yes,默认 AOF 持久化的基本文件为 rdb 格式文件,也就是默认采用混合式持久化

(4) AOF 文件目录配置

为了方便管理,可以专门为 AOF 持久化文件指定存放目录。目录名由 appenddirname 属性指定,默认为 Redis 安装目录。

4.3.2 AOF 文件格式

AOF 文件包含三类文件:基本文件、增量文件与清单文件。其中基本文件一般为 rdb 格 式,在前面已经研究过了。下面就来看一下增量文件与清单文件的内容格式。

(1) Redis 协议

增量文件扩展名为.aof,采用 AOF 格式。AOF 格式就是 Redis 通讯协议格式,AOF 持久化文件的本质就是基于 Redis 通讯协议的文本,将命令以纯文本的方式写入到文件中。

Redis 协议规定,Redis 文本是以行来划分,每行以\r\n 行结束。每一行都有一个消息头,以表示消息类型。消息头由六种不同的符号表示,其意义如下:

  • (+) 表示一个正确的状态信息
  • (-) 表示一个错误信息
  • (*) 表示消息体总共有多少行,不包括当前行
  • ($) 表示下一行消息数据的长度,不包括换行符长度\r\n
  • (空) 表示一个消息数据
  • (:) 表示返回一个数值

(2) 查看 AOF 文件

打开 appendonly.aof.1.incr.aof 文件,可以看到如下格式内容。 image.png image.png

(3) 清单文件

打开清单文件 appendonly.aof.manifest,查看其内容如下: image.png 该文件首先会按照 seq 序号列举出所有基本文件,基本文件 type 类型为 b,然后再按照 seq 序号再列举出所有增量文件,增量文件 type 类型为 i。 Redis 启动时的数据恢复按照该文件由上到下依次加载它们中的数据。

4.3.3 Rewrite 机制

为了防止 AOF 文件由于太大而占用大量的磁盘空间,降低性能,Redis 引入了 Rewrite 机制来对 AOF 文件进行压缩。

(1) 何为 rewrite

Rewrite 其实就是对 AOF 文件进行重写整理。当 Rewrite 开启后,主进程 redis-server 创建出一个子进程 bgrewriteaof,由该子进程完成 rewrite 过程。其首先对现有 aof 文件进行 rewrite 计算,将计算结果写入到一个临时文件,写入完毕后覆盖原有文件。

(2) rewrite 计算 也称为 rewrite 策略。遵循以下策略:读操作命令不写入文件,无效命令不写入文件,过期数据不写入文件, 多条命令合并写入文件

(3) 手动开启 rewrite

bgrewriteaof 命令:使主进程 redis-server 创建出一个子进程 bgrewriteaof,由该子进程完成 rewrite 过程。而在 rewrite 期间,redis-server 仍是可以对外提供读写服务的。

(4) 自动开启 rewrite

手动方式需要人工干预,所以一般采用自动方式。由于 Rewrite 过程是一个计算过程,消耗大量系统资源,会降低系统性能。所以 Rewrite 并不是随时随地任意开启的, 而是通过设置一些条件,满足条件后才会启动,以降低对性能的影响。 image.png

  • auto-aof-rewrite-percentage:开启 rewrite 的增大比例,默认 100%。指定为 0,表示禁用自动 rewrite。
  • auto-aof-rewrite-min-size:开启 rewrite 的 AOF 文件最小值,默认 64M。

自动重写 AOF 文件。当 AOF 日志文件大小增长到指定的百分比时,Redis 主进程 redis-server 会 fork 出一个子进程 bgrewriteaof 来完成 rewrite 过程。

其工作原理如下:Redis 记住最新 rewrite 后的 AOF 文件大小作为基本大小,如果从主机启动后就没有发生过重写,则基本大小就使用启动时 AOF 的大小。 如果当前 AOF 文件大于基本大小的配置文件中指定的百分比阈值,且大于配置文件中指定的最小阈值,触发 rewrite。

4.3.4 AOF 优化配置

(1) appendfsync

image.png

当客户端提交写操作命令后,该命令就会写入到 aof_buf 中,而 aof_buf 中的数据持久化到磁盘 AOF 文件的过程称为数据同步。 何时将 aof_buf 中的数据同步到 AOF 文件?采用不同的数据同步策略,同步的时机是不同的,有三种策略:

  • always:写操作命令写入 aof_buf 后会立即调用 fsync()系统函数,将其追加到 AOF 文件。该策略效率较低,但相对比较安全,不会丢失太多数据。最多就是刚刚执行过的写操作在尚未同步时出现宕机或重启,将这一操作丢失。
  • no:写操作命令写入 aof_buf 后什么也不做,不会调用 fsync()函数。而将 aof_buf 中的数据同步磁盘的操作由操作系统负责。Linux 系统默认同步周期为 30 秒。效率较高。
  • everysec:默认策略。写操作命令写入 aof_buf 后并不直接调用 fsync(),而是每秒调用一次 fsync()系统函数来完成同步。该策略兼顾到了性能与安全,是一种折中方案。

(2) no-appendfsync-on-rewrite

该属性用于指定,当 AOF fsync 策略设置为 always 或 everysec,当主进程创建了子进程正在执行 bgsave 或 bgrewriteaof 时,主进程是否不调用 fsync()来做数据同步。设置为 no,双重否定即肯定,主进程会调用 fsync()做同步。而 yes 则不会调用 fsync()做数据同步。

如果调用 fsync(),在需要同步的数据量非常大时,会阻塞主进程对外提供服务,即会存在延迟问题。如果不调用 fsync(),则 AOF fsync 策略相当于设置为了 no,可能会存在 30 秒数据丢失的风险。

(3) aof-rewrite-incremental-fsync

当 bgrewriteaof 在执行过程也是先将 rewrite 计算的结果写入到了 aof_rewrite_buf 缓存中,然后当缓存中数据达到一定量后就会调用 fsync()进行刷盘操作,即数据同步,将数据写入到临时文件。该属性用于控制 fsync()每次刷盘的数据量最大不超过 4MB。这样可以避免由于单次刷盘量过大而引发长时间阻塞。

(4) aof-load-truncated

在进行 AOF 持久化过程中可能会出现系统突然宕机的情况,此时写入 AOF 文件的最后一条数据可能会不完整。当主机启动后,Redis 在 AOF 文件不完整的情况下是否可以启动,取决于属性 aof-load-truncated 的设置。其值为:

  • yes:AOF 文件最后不完整的数据直接从 AOF 文件中截断删除,不影响 Redis 的启动。
  • no:AOF 文件最后不完整的数据不可以被截断删除,Redis 无法启动。

(5) aof-timestamp-enabeld

该属性设置为 yes 则会开启在 AOF 文件中增加时间戳的显示功能,可方便按照时间对数据进行恢复。但该方式可能会与 AOF 解析器不兼容,所以默认值为 no,不开启。

4.3.5 AOF持久化过程

image.png

  1. Redis 接收到的写操作命令并不是直接追加到磁盘的 AOF 文件,而是将每一条写命令按照 redis 通讯协议格式暂时添加到 AOF 缓冲区 aof_buf。
  2. 根据设置的数据同步策略,当同步条件满足时,再将缓冲区中的数据一次性写入磁盘的 AOF 文件,以减少磁盘 IO 次数,提高性能。
  3. 当磁盘的 AOF 文件大小达到了 rewrite 条件时,redis-server 主进程会 fork 出一个子进程 bgrewriteaof,由该子进程完成 rewrite 过程。
  4. 子进程 bgrewriteaof 首先对该磁盘 AOF 文件进行 rewrite 计算,将计算结果写入到一个临时文件,全部写入完毕后,再 rename 该临时文件为磁盘文件的原名称,覆盖原文件。
  5. 如果在 rewrite 过程中又有写操作命令追加,那么这些数据会暂时写入 aof_rewrite_buf 缓冲区。等将全部 rewrite 计算结果写入临时文件后,会先将 aof_rewrite_buf 缓冲区中的数据写入临时文件,然后再 rename 为磁盘文件的原名称,覆盖原文件。

4.4 RDB 与 AOF 对比

4.4.1 RDB 优势与不足

(1) RDB 优势

  • RDB 文件较小
  • 数据恢复较快

(2) RDB 不足

  • 数据安全性较差
  • 写时复制会降低性能
  • RDB 文件可读性较差
4.4.2 AOF 优势与不足

(1) AOF 优势

  • 数据安全性高
  • AOF 文件可读性强

(2) AOF 不足

  • AOF 文件较大
  • 写操作会影响性能
  • 数据恢复较慢

4.5 持久化技术选型

  • 官方推荐使用 RDB 与 AOF 混合式持久化。
  • 若对数据安全性要求不高,则推荐使用纯 RDB 持久化方式。
  • 不推荐使用纯 AOF 持久化方式。
  • 若 Redis 仅用于缓存,则无需使用任何持久化技术。