RDB-AOF混合持久化

在前面的内容中,我们考察了Redis的两种持久化方式,它们都有各自 的优点和缺点:

  • RDB持久化可以生成紧凑的RDB文件,并且使用RDB文件进行数据恢复 的速度也非常快,但是RDB的全量持久化模式可能会让服务器在停机时 丢失大量数据。

  • 与RDB持久化相比,AOF持久化可以将丢失数据的时间窗口限制在1s 之内,但是协议文本格式的AOF文件的体积将比RDB文件要大得多,并 且数据恢复过程也会相对较慢。

由于RDB持久化和AOF持久化都有各自的优缺点,因此在很长一段时间 里,如何选择合适的持久化方式成了很多Redis用户面临的一个难题。 为了解决这个问题,Redis从4.0版本开始引入RDB-AOF混合持久化模 式,这种模式是基于AOF持久化模式构建而来的——如果用户打开了服 务器的AOF持久化功能,并且将

aof-use-rdb-preamble <value>

选项的值设置成了yes,那么Redis服务器在执行AOF重写操作时,就会 像执行BGSAVE命令那样,根据数据库当前的状态生成出相应的RDB数 据,并将这些数据写入新建的AOF文件中,至于那些在AOF重写开始之 后执行的Redis命令,则会继续以协议文本的方式追加到新AOF文件的 末尾,即已有的RDB数据的后面。

换句话说,在开启了RDB-AOF混合持久化功能之后,服务器生成的AOF 文件将由两个部分组成,其中位于AOF文件开头的是RDB格式的数据, 而跟在RDB数据后面的则是AOF格式的数据,如图15-8所示。

image 2025 01 05 22 33 00 429
Figure 1. 图15-8 RDB-AOF混合持久化功能生成的AOF文件

举个例子,通过执行以下Redis命令:

redis> SET MSG "HELLO WORLD"
OK
redis> SET NUMBER "10086"
OK
redis> SET URL "REDIS.IO"
OK
redis> BGREWRITEAOF -- 触发重写,将之前的键值对存储为RDB格式
Background append only file rewriting started
redis> SADD FRUITS "APPLE" "BANANA" "CHERRY"
(integer) 3
redis> ZADD NUM-LIST 3.14 "PI" 1.28 "X" 2.56 "Y"
(integer) 3

服务器将生成包含以下内容的AOF文件:

$ od -c appendonly.aof
0000000 R E D I S 0 0 0 9 372 \t r e d i s
0000020 - v e r \v 9 9 9 . 9 9 9 . 9 9 9
0000040 372 \n r e d i s - b i t s 300 @ 372 005
0000060 c t i m e 302 O 325 374 \ 372 \b u s e d
0000100 - m e m ° ** 4 020 \0 372 \f a o f - p
0000120 r e a m b l e 300 001 376 \0 373 003 \0 \0 003
0000140 M S G \v H E L L O W O R L D \0
0000160 003 U R L \b R E D I S . I O \0 006 N
0000200 U M B E R 301 f ' 377 240 : 235 h ** **
0000220 304 * 2 \r \n $ 6 \r \n S E L E C T \r
0000240 \n $ 1 \r \n 0 \r \n * 5 \r \n $ 4 \r \n
0000260 S A D D \r \n $ 6 \r \n F R U I T S
0000300 \r \n $ 5 \r \n A P P L E \r \n $ 6 \r
0000320 \n B A N A N A \r \n $ 6 \r \n C H E
0000340 R R Y \r \n * 8 \r \n $ 4 \r \n Z A D
0000360 D \r \n $ 8 \r \n N U M - L I S T \r
0000400 \n $ 4 \r \n 3 . 1 4 \r \n $ 2 \r \n P
0000420 I \r \n $ 4 \r \n 1 . 2 8 \r \n $ 1 \r
0000440 \n X \r \n $ 4 \r \n 2 . 5 6 \r \n $ 1
0000460 \r \n Y \r \n

从od程序的输出可以看到,文件上半部分包含的是RDB格式的二进制数 据,而后半部分包含的则是AOF格式的协议文本数据。

当一个支持RDB-AOF混合持久化模式的Redis服务器启动并载入AOF文件 时,它会检查AOF文件的开头是否包含了RDB格式的内容:

  • 如果包含,那么服务器就会先载入开头的RDB数据,然后再载入之后的AOF数据。

  • 如果AOF文件只包含AOF数据,那么服务器将直接载入AOF数据。

图15-9展示了这一判断过程。

image 2025 01 05 22 34 35 009
Figure 2. 图15-9 Redis服务器在载入AOF文件时执行的判断流程

通过使用RDB-AOF混合持久化功能,用户可以同时获得RDB持久化和AOF 持久化的优点:服务器既可以通过AOF文件包含的RDB数据来实现快速 的数据恢复操作,又可以通过AOF文件包含的AOF数据来将丢失数据的 时间窗口限制在1s之内。

需要注意的是,因为RDB-AOF混合持久化生成的AOF文件会同时包含RDB 格式的数据和AOF格式的数据,而传统的AOF持久化只会生成包含AOF格 式的数据,所以为了避免全新的RDB-AOF混合持久化功能给传统的AOF 持久化功能使用者带来困惑,Redis目前默认是没有打开RDB-AOF混合 持久化功能的:

aof-use-rdb-preamble no

但是Redis的作者声称,RDB-AOF混合持久化将在未来取代传统的RDB持 久化成为Redis默认的持久化模式。