Redis 持久化——混合持久化
1、Redis 持久化——混合持久化
RDB 和 AOF 持久化各有利弊,RDB 可能会导致一定时间内的数据丢失,而 AOF 由于文件较大则会影响 Redis 的启动速度,为了能同时使用 RDB 和 AOF 各种的
优点,Redis 4.0 之后新增了混合持久化的方式
在开启混合持久化的情况下,AOF rewrite 重写时会创建一个新的AOF文件,把 Redis 的持久化数据,以 RDB 的格式写入到 AOF 文件的开头,之后的数据再以 AOF 的格式化追加的文件的末尾,
当重写完成后,新的AOF文件将替换旧的AOF文件,旧的AOF文件则被清除
混合持久化的数据存储结构如下图所示:

1、开启混合持久化
查询是否开启混合持久化可以使用 config get aof-use-rdb-preamble 命令,执行结果如下图所示:

其中 yes 表示已经开启混合持久化,no 表示关闭,Redis 5.0 默认值为 yes。 如果是其他版本的 Redis 首先需要检查一下,是否已经开启了混合持久化,如果关闭的情况下,
可以通过以下两种方式开启:
-
通过命令行开启
-
通过修改 Redis 配置文件开启
2、通过命令行开启
使用命令 config set aof-use-rdb-preamble yes 执行结果如下图所示:

小贴士:命令行设置配置的缺点是重启 Redis 服务之后,设置的配置就会失效。
3、通过修改 Redis 配置文件开启
在 Redis 的根路径下找到 redis.conf 文件,把配置文件中的 aof-use-rdb-preamble no 改为 aof-use-rdb-preamble yes 如下图所示:

2、实例运行
当在混合持久化关闭的情况下,使用 bgrewriteaof 手动触发 AOF 文件重写之后,查看 appendonly.aof 文件的持久化日志,如下图所示:

可以看出,当混合持久化关闭的情况下 AOF 持久化文件存储的为标准的 AOF 格式的文件。 当混合持久化开启的模式下,使用 bgrewriteaof 命令触发 AOF 文件重写,
得到 appendonly.aof 的文件内容如下图所示:

可以看出 appendonly.aof 文件存储的内容是 Redis 开头的 RDB 格式的内容,并非为 AOF 格式的日志。
3、数据恢复和源码解析
混合持久化的数据恢复和 AOF 持久化过程是一样的,只需要把 appendonly.aof 放到 Redis 的根目录,在 Redis 启动时,
只要开启了 AOF 持久化,Redis 就会自动加载并恢复数据。 Redis 启动信息如下图所示:

可以看出 Redis 在服务器初始化的时候加载了 AOF 文件的内容。
a、混合持久化的加载流程
混合持久化的加载流程如下:
-
1、判断是否开启 AOF 持久化,开启继续执行后续流程,未开启执行加载 RDB 文件的流程;
-
2、判断 appendonly.aof 文件是否存在,文件存在则执行后续流程;
-
3、判断 AOF 文件开头是 RDB 的格式, 先加载 RDB 内容再加载剩余的 AOF 内容;
-
4、判断 AOF 文件开头不是 RDB 的格式,直接以 AOF 格式加载整个文件。
AOF 加载流程图如下图所示:

4、手动重写 与 自动重写
a、手动重写
AOF 重写程序 aof_rewrite 函数可以创建一个新 AOF 文件, 但是该函数会进行大量的写入操作,调用这个函数的线程将被长时间阻塞,
所以 Redis 将 AOF 重写程序放到 fork 的子进程里执行,不会阻塞父进程,重写命令:
bgrewriteaof
-
子进程进行 AOF 重写期间,服务器进程(父进程)可以继续处理命令请求
-
子进程带有服务器进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下, 保证数据安全性

子进程在进行 AOF 重写期间,服务器进程还需要继续处理命令请求,而新命令可能会对现有的数据库状态进行修改,
从而使得服务器当前的数据库状态和重写后的 AOF 文件所保存的数据库状态不一致,所以 Redis 设置了 AOF 重写缓冲区
工作流程:
-
Redis 服务器执行完一个写命令,会同时将该命令追加到 AOF 缓冲区和 AOF 重写缓冲区(从创建子进程后才开始写入)
-
当子进程完成 AOF 重写工作之后,会向父进程发送一个信号,父进程在接到该信号之后, 会调用一个信号处理函数,该函数执行时会对服务器进程(父进程)造成阻塞(影响很小,类似 JVM STW),主要工作:
-
将 AOF 重写缓冲区中的所有内容写入到新 AOF 文件中, 这时新 AOF 文件所保存的状态将和服务器当前的数据库状态一致
-
对新的 AOF 文件进行改名,原子地(atomic)覆盖现有的 AOF 文件,完成新旧两个 AOF 文件的替换
-
b、自动重写
触发时机:Redis 会记录上次重写时的 AOF 大小,默认配置是当 AOF 文件大小是上次重写后大小的一倍且文件大于 64M 时触发
auto-aof-rewrite-min-size size #设置重写的基准值,最小文件 64MB,达到这个值开始重写
auto-aof-rewrite-percentage percent #触发AOF文件执行重写的增长率,当前AOF文件大小超过上一次重写的AOF文件大小的百分之多少才会重写,比如文件达到 100% 时开始重写就是两倍时触发
自动重写触发比对参数( 运行指令 info Persistence 获取具体信息 ):
aof_current_size #AOF文件当前尺寸大小(单位:字节)
aof_base_size #AOF文件上次启动和重写时的尺寸大小(单位:字节)
自动重写触发条件公式:
- aof_current_size > auto-aof-rewrite-min-size
- (aof_current_size - aof_base_size) / aof_base_size >= auto-aof-rewrite-percentage

浙公网安备 33010602011771号