文章目录
- 一 AOF(Append Only File) 持久化
- 二 AOF 基础配置
- 2.1 AOF的开启
- 2.2 文件名配置
- 2.3 混合式持久化开启
- 2.4 AOF 文件目录配置
- 三 AOF 文件格式
- 3.1 Redis 协议
- 3.2 查看 AOF 文件
- 3.3 清单文件
- 3.4 Rewrite 机制
- 3.4.1 rewrite简介
- 3.4.2 rewrite 计算策略
- 3.4.3 手动开启 rewrite
- 3.4.4 自动开启 rewrite
- 四 AOF 优化配置
- 4.1 appendfsync
- 4.2 no-appendfsync-on-rewrite
- 4.3 aof-rewrite-incremental-fsync
- 4.5 aof-load-truncated
- 4.6 aof-timestamp-enabeld
- 4.7 AOF 持久化过程
- 五 总结
- 5.1 RDB 与 AOF 对比
- 5.2 持久化技术建议
一 AOF(Append Only File) 持久化
- AOF指 Redis 将每一次的写操作都以日志的形式记录到一个 AOF文件中的持久化技术。当需要恢复内存数据时,将这些写操作重新执行一次,便会恢复到之前的内存数据状态。
二 AOF 基础配置
2.1 AOF的开启
- 默认情况下 AOF 持久化是没有开启的,通过修改配置文件
redis.conf
中的appendonly
属性为yes
开启
- 默认情况下,Redis异步将数据集转储到磁盘上。这个模式在许多应用程序中已经足够好了,但是Redis进程或停电可能会导致几分钟的写入丢失(取决于配置的保存点)。
- 断电可能会导致几分钟的写入丢失(取决于配置的保存点)。仅追加文件是另一种持久性模式,它提供了更好的持久性。例如,使用默认的数据fsync策略(参见后面的配置文件),Redis可以在一个突发的事件中丢失一秒钟的写,比如服务器断电,或者如果Redis进程本身发生了一些错误,那么一个写,但操作系统仍然正常运行。
- AOF和RDB持久性可以同时启用,没有问题。如果启动时启用AOF, Redis将加载AOF,这是具有更好的持久性保证的文件。
- 更多信息请登录https://redis.io/topics/persistence
2.2 文件名配置
- 附加文件的基本名称。
- **Redis 7和更新版本使用一组只能追加的文件来持久化数据集和应用于它的更改。**使用的文件有两种基本类型:
- 基本文件,这是一个快照,表示文件创建时数据集的完整状态。基本文件可以是RDB(二进制序列化)或AOF(文本命令)的形式。
- 增量文件,其中包含应用于前一个文件之后的数据集的额外命令。
- 此外,清单文件用于跟踪文件及其创建和应用的顺序。
- 只能追加的文件名是由Redis按照特定的模式创建的。
- 文件名的前缀基于’appendfilename’配置参数,后面跟着关于序列和类型的附加信息。
- 例如,如果appendfilename设置为appendonly。附加文件可以推导出以下文件名:
appendonly.aof.1.base.rdb
作为基本文件。appendonly.aof.1.incr. aof appendonly.aof.2.incr
作为增量文件。appendonly.aof.manifest
作为清单文件。
- 基本文件:可以是 RDF 格式也可以是 AOF 格式。其存放的内容是由 RDB 转为 AOF 当时内存的快照数据,该文件可以有多个。
- 增量文件:以操作日志形式记录转为 AOF 后的写入操作。该文件可以有多个。
- 清单文件:用于维护 AOF 文件的创建顺序,保障激活时的应用顺序。该文件只有一个
2.3 混合式持久化开启
- 对于基本文件可以是 RDF 格式也可以是 AOF 格式。通过 aof-use-rdb-preamble 属性可以选择。其默认值为 yes,即默认 AOF 持久化的基本文件为 rdb 格式文件,也就是默认采用混合式持久化
2.4 AOF 文件目录配置
- 为了方便,Redis将所有持久的仅追加文件存储在专用目录中。目录的名称由appenddirname配置参数决定。存放在 redis.conf 配置文件的 dir 属性指定的目录,默认为 Redis 安装目录
三 AOF 文件格式
- AOF 文件包含三类文件:基本文件、增量文件与清单文件。
3.1 Redis 协议
- 增量文件扩展名为.aof,采用 AOF 格式。AOF 格式其实就是 Redis 通讯协议格式,AOF持久化文件的本质就是基于 Redis 通讯协议的文本,将命令以纯文本的方式写入到文件中。
- Redis 协议规定,Redis 文本是以行来划分,每行以\r\n 行结束。每一行都有一个消息头,以表示消息类型。消息头由六种不同的符号表示,其意义如下:
符号 | 解释 |
---|---|
+ | 表示一个正确的状态信息 |
- | 表示一个错误信息 |
* | 表示消息体总共有多少行,不包括当前行 |
$ | 表示下一行消息数据的长度,不包括换行符长度\r\n |
空 | 表示一个消息数据 |
: | 表示返回一个数值 |
3.2 查看 AOF 文件
- 启动Redis,打开客户端后执行以下代码
select 0 set key1 value1
- 打开
appendonly.aof.1.incr.aof
文件
*2 -- 表示当前命令包含 2 个参数
$6 -- 表示第 1 个参数包含 6 个字符
SELECT -- 第 1 个参数
$1 -- 表示第 2 个参数包含 1 个字符
0 -- 第 2 个参数
*3 --表示当前命令包含 3 个参数
$3 -- 表示第 1 个参数包含 3 个字符
set -- 第 1 个参数
$3 -- 表示第 2 个参数包含 3 个字符
keys -- 第 2 个参数
$3 -- 表示第 3 个参数包含 2 个字符
value1 -- 第 3 个参数
3.3 清单文件
- 打开清单文件
appendonly.aof.manifes
- 该文件首先会按照 seq 序号列举出所有基本文件,基本文件 type 类型为 b,然后再按照seq 序号再列举出所有增量文件,增量文件 type 类型为 i。
- 对于 Redis 启动时的数据恢复,也会按照该文件由上到下依次加载它们中的数据。
3.4 Rewrite 机制
- 为了防止 AOF 文件由于太大而占用大量的磁盘空间,降低性能,Redis 引入了
Rewrite
机制来对 AOF 文件进行压缩。
3.4.1 rewrite简介
- Rewrite 就是对 AOF 文件进行重写整理。
- 当 Rewrite 开启后,主进程
redis-server
创建出一个子进程bgrewriteaof
,由该子进程完成rewrite
过程。其首先对现有 aof 文件进行rewrite
计算,将计算结果写入到一个临时文件,写入完毕后,再rename
该临时文件为原aof
文件名,覆盖原有文件。
3.4.2 rewrite 计算策略
rewrite
计算也称为rewrite
策略。rewrite
计算遵循以下策略:- 读操作命令不写入文件
- 无效命令不写入文件
- 过期数据不写入文件
- 多条命令合并写入文件
3.4.3 手动开启 rewrite
- Rewrite 过程的执行有两种方式。一种是通过 bgrewriteaof 命令手动开启,另一种是通过设置条件自动开启。
- 以下是手动开启方式:
bgwriteaof
- 该命令会使主进程 redis-server 创建出一个子进程 bgrewriteaof,由该子进程完成 rewrite过程。而在 rewrite 期间,redis-server 仍是可以对外提供读写服务的。
3.4.4 自动开启 rewrite
- 手动方式需要人办干预,所以一般采用自动方式。由于 Rewrite 过程是一个计算过程,需要消耗大量系统资源,会降低系统性能。所以,Rewrite 过程并不是随时随地任意开启的,而是通过设置一些条件,当满足条件后才会启动,以降低对性能的影响。
- 配置文件中对于
Rewrite
自动启动条件的设置
auto-aof-rewrite-percentage
:开启rewrite
的增大比例,默认 100%。指定为 0,表示禁用自动 rewrite。auto-aof-rewrite-min-size
:开启 rewrite 的 AOF 文件最小值,默认 64M。该值的设置主要是为了防止小 AOF 文件被 rewrite,从而导致性能下降。
- 自动重写 AOF 文件。当 AOF 日志文件大小增长到指定的百分比时,Redis 主进程
redis-server
会 fork 出一个子进程bgrewriteaof
来完成rewrite
过程。 - 其工作原理如下:Redis 会记住最新 rewrite 后的 AOF 文件大小作为基本大小,如果从主机启动后就没有发生过重写,则基本大小就使用启动时 AOF 的大小。 如果当前 AOF 文件大于基本大小的配置文件中指定的百分比阈值,且当前 AOF 文件大于配置文件中指定的最小阈值,则会触发 rewrite。
四 AOF 优化配置
4.1 appendfsync
- fsync()调用告诉操作系统实际将数据写入磁盘,而不是在输出缓冲区中等待更多数据。有些操作系统真的会刷新磁盘上的数据,有些操作系统只会尽快这么做。
- Redis支持三种不同的模式
- no:不要fsync,让操作系统在需要的时候刷新数据。得更快。
- always:每次写入只追加日志后进行fsync。缓慢的,安全的。
- everysec:每秒只同步一次。妥协。
- 默认是“everysec”,因为这通常是速度和数据安全之间的正确妥协。这取决于您是否可以将其放宽为“no”,从而让操作系统在需要时刷新输出缓冲区,以获得更好的性能(但如果您可以接受一些数据丢失的想法,请考虑默认的持久性模式快照),或者相反,使用“always”,这非常慢,但比“always”更安全
当客户端提交写操作命令后,该命令就会写入到 aof_buf 中,而 aof_buf 中的数据持久化到磁盘 AOF 文件的过程称为数据同步。
- 采用不同的数据同步策略,同步的时机是不同的,有三种策略:
- always:写操作命令写入 aof_buf 后会立即调用 fsync()系统函数,将其追加到 AOF 文件。
- 该策略效率较低,但相对比较安全,不会丢失太多数据。最多就是刚刚执行过的写操作在尚未同步时出现宕机或重启,将这一操作丢失。
- no:写操作命令写入 aof_buf 后什么也不做,不会调用 fsync()函数。
- 而将 aof_buf 中的数据同步磁盘的操作由操作系统负责。Linux 系统默认同步周期为 30 秒。效率较高。
- everysec:默认策略。写操作命令写入 aof_buf 后并不直接调用 fsync(),而是每秒调用一次 fsync()系统函数来完成同步。
- 该策略兼顾到了性能与安全,是一种折中方案
- always:写操作命令写入 aof_buf 后会立即调用 fsync()系统函数,将其追加到 AOF 文件。
4.2 no-appendfsync-on-rewrite
- 当 AOF fsync 策略设置为 always 或 everysec,当主进程创建了子进程正在执行 bgsave 或 bgrewriteaof 时,主进程是否不调用 fsync()来做数据同步。设置为 no,双重否定即肯定,主进程会调用 fsync()做同步。而 yes 则不会调用 fsync()做数据同步。
- 如果调用 fsync(),在需要同步的数据量非常大时,会阻塞主进程对外提供服务,即会存在延迟问题。如果不调用 fsync(),则 AOF fsync 策略相当于设置为了 no,可能会存在 30 秒数据丢失的风险。
4.3 aof-rewrite-incremental-fsync
- 当 bgrewriteaof 在执行过程也是先将 rewrite 计算的结果写入到了 aof_rewrite_buf 缓存中,然后当缓存中数据达到一定量后就会调用fsync()进行刷盘操作,即数据同步,将数据写入到临时文件。该属性用于控制 fsync()每次刷盘的数据量最大不超过 4MB。这样可以避免由于单次刷盘量过大而引发长时间阻塞。
4.5 aof-load-truncated
- 在进行 AOF 持久化过程中可能会出现系统突然宕机的情况,此时写入到 AOF 文件中的最后一条数据可能会不完整。当主机启动后,Redis 在 AOF 文件不完整的情况下是否可以启动,取决于属性
aof-load-truncated
的设置。- yes:AOF 文件最后不完整的数据直接从 AOF 文件中截断删除,不影响 Redis 的启动。
- no:AOF 文件最后不完整的数据不可以被截断删除,Redis 无法启动。
4.6 aof-timestamp-enabeld
- 该属性设置为 yes 则会开启在 AOF 文件中增加时间戳的显示功能,可方便按照时间对数据进行恢复。
- 但该方式可能会与 AOF 解析器不兼容,所以默认值为 no,不开启。
4.7 AOF 持久化过程
- AOF 详细的持久化过程如下:
- Redis 接收到的写操作命令并不是直接追加到磁盘的 AOF 文件的,而是将每一条写命令按照 redis 通讯协议格式暂时添加到 AOF 缓冲区 aof_buf。
- 根据设置的数据同步策略,当同步条件满足时,再将缓冲区中的数据一次性写入磁盘的AOF 文件,以减少磁盘 IO 次数,提高性能。
- 当磁盘的 AOF 文件大小达到了 rewrite 条件时,redis-server 主进程会 fork 出一个子进程bgrewriteaof,由该子进程完成 rewrite 过程。
- 子进程 bgrewriteaof 首先对该磁盘 AOF 文件进行 rewrite 计算,将计算结果写入到一个临时文件,全部写入完毕后,再 rename 该临时文件为磁盘文件的原名称,覆盖原文件。
- 如果在 rewrite 过程中又有写操作命令追加,那么这些数据会暂时写入 aof_rewrite_buf缓冲区。等将全部 rewrite 计算结果写入临时文件后,会先将 aof_rewrite_buf 缓冲区中的数据写入临时文件,然后再 rename 为磁盘文件的原名称,覆盖原文件。
五 总结
5.1 RDB 与 AOF 对比
持久化技术 | 优势 | 不足 |
---|---|---|
RDB | RDB 文件较小 数据恢复较快 | 数据安全性较差 写时复制会降低性能 RDB 文件可读性较差 |
AOF | 数据安全性高 AOF 文件可读性强 | AOF 文件较大 写操作会影响性能 数据恢复较慢 |
5.2 持久化技术建议
- 官方推荐使用 RDB 与 AOF 混合式持久化。
- 若对数据安全性要求不高,则推荐使用纯 RDB 持久化方式。
- 不推荐使用纯 AOF 持久化方式。
- 若 Redis 仅用于缓存,则无需使用任何持久化技术