Redis 的 RDB 持久化机制简单直接,把某一时刻的所有键值对以二进制的方式写入到磁盘,特点是恢复速度快,尤其适合数据备份、主从复制场景。但如果你的目的是要保证数据可靠性,RDB 就不太适合了,因为 RDB 持久化不宜频繁触发,如果 Redis 触发 RDB 后又有新的数据写入,且还没来得及触发下一次 RDB 就宕机了,中间的数据就会丢失。
在这种场景下,我们就急需一种增量备份的方式,只记录上一次 RDB 到现在为止所有的变更记录就好了,相较于全量备份,增量备份的数据量就小得多了。所以,Redis 还提供了 AOF 持久化机制。
特性 | RDB | AOF |
---|---|---|
文件格式 | 二进制 | 文本 |
内存效率 | 高 | 较低 |
恢复速度 | 快 | 慢 |
文件大小 | 小 | 大 |
运行效率 | 高 | 低 |
Redis 会把服务端执行的所有写命令,以 RESP 协议的方式追加到 AOF 日志文件中,数据恢复时只要读取 AOF 文件,重放所有的日志即可。
开启 AOF 你需要关心下面几个参数:
#开启AOF
appendonly yes
appendfilename "appendonly.aof" #AOF文件名#AOF文件刷盘策略
appendfsync always
# appendfsync everysec
# appendfsync no#AOF触发机制
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb#是否开启RDB前导 混合持久化
aof-use-rdb-preamble yes
appendfsync 配置 AOF 文件刷盘策略:
建议设置为 everysec,兼顾性能和可靠性,最多丢失一秒的数据;always 虽然足够可靠,但是会严重拉低性能;no 会让 AOF 文件刷盘的时机脱离 Redis 的控制,并不推荐。
开启 AOF 不代表就可以高枕无忧了,因为 AOF 是日志追加的形式,意味着随着不断运行,AOF 日志会越来越大。AOF 日志文件膨胀会带来两个问题:
所以,Redis 会对 AOF 文件重写,手动与自动两种方式:
为什么重写可以缩小 AOF 文件呢?因为可以把多条命令合并成一条命令,AOF 只需要记录 Key 最新的 Value 即可,而不用记录修改的历史记录(比如多次set值,只留下最后一次的)。
最后是aof-use-rdb-preamble
参数,它是 Redis4 才开始支持的混合持久化机制,开启后 AOF 重写时将会在 AOF 文件的前半部分先写入全量的 RDB 数据,再把增量 AOF 日志追加在后半部分,同时兼顾了性能和可靠性,建议开启。
*
代表数组,后面跟着数组长度$
代表字符串,后面跟着长度127.0.0.1:6379> set name Jackson
OK
127.0.0.1:6379> lpush names Lisa
(integer) 1
127.0.0.1:6379> lpush names Tom
(integer) 2
我们来解读一下这段日志,
首先是SELECT 0(
代表后续操作的是 0 号数据库):
【数组长度2】【字符串长度6】SELECT
【字符串长度1】0。
然后是我们执行的代码set name Jackson:【数组长度3】【字符串长度3】SET
【字符串长度4】name【字符串长度7】Jackson ... ...后面就省略不说了。
(注意:读命令不会对数据有影响,是不会记录到 AOF 文件的)
*2
$6
SELECT
$1
0
*3
$3
set
$4
name
$7
Jackson
*3
$5
lpush
$5
names
$4
Lisa
*3
$5
lpush
$5
names
$3
Tom
此时我们执行bgrewriteaof
命令重写 AOF 文件,再次查看发现 AOF 文件确实变小了,两次LPUSH合并为一次RPUSH
了。
*2
$6
SELECT
$1
0
*3
$3
SET
$4
name
$7
Jackson
*4
$5
RPUSH
$5
names
$3
Tom
$4
Lisa
如果开启了混合持久化,我们再执行bgrewriteaof
命令重写 AOF 文件,会发现 AOF 文件不可读了,因为此时里面的内容是二进制的 RDB 数据(此时好没有AOF数据)。如下:
REDIS0009� redis-ver6.2.13�
redis-bits�@�ctime·�"eused-mem�`�
aof-preamble���nameJacksonnamesTomLisa��=O{�v�*2
再执行一条命令写进去:
127.0.0.1:6379> del name
(integer) 1
再查看 AOF 文件会发现,前半段是不可读的 RDB 数据,后半段是可读的 AOF 日志,这就是混合持久化。
REDIS0009� redis-ver6.2.13�
redis-bits�@�ctime·�"eused-mem�`�
aof-preamble���nameJacksonnamesTomLisa��=O{�v�*2
$6
SELECT
$1
0
*2
$3
del
$4
name
参考自:Redis AOF持久化和ReWrite_aof rewrite-CSDN博客