Redis RDB与AOF持久化、RESP 协议和ReWrite重写缩减体积

前言

Redis 的 RDB 持久化机制简单直接,把某一时刻的所有键值对以二进制的方式写入到磁盘,特点是恢复速度快,尤其适合数据备份、主从复制场景。但如果你的目的是要保证数据可靠性,RDB 就不太适合了,因为 RDB 持久化不宜频繁触发,如果 Redis 触发 RDB 后又有新的数据写入,且还没来得及触发下一次 RDB 就宕机了,中间的数据就会丢失。
在这种场景下,我们就急需一种增量备份的方式,只记录上一次 RDB 到现在为止所有的变更记录就好了,相较于全量备份,增量备份的数据量就小得多了。所以,Redis 还提供了 AOF 持久化机制。

  • RDB 二进制 高效 体积小
  • AOF 文本 低效 体积大
特性 RDB AOF
文件格式 二进制 文本
内存效率 较低
恢复速度
文件大小
运行效率

Redis 会把服务端执行的所有写命令,以 RESP 协议的方式追加到 AOF 日志文件中,数据恢复时只要读取 AOF 文件,重放所有的日志即可。

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

AOF刷盘策略

appendfsync 配置 AOF 文件刷盘策略:

  • always:每个写命令执行完都立即同步到磁盘,可靠性高、效率低
  • everysec:AOF 日志先写入内存缓冲区,再由定时任务每秒刷一次盘
  • no:AOF 日志只写入操作系统文件缓存,由操作系统决定刷盘时机

建议设置为 everysec,兼顾性能和可靠性,最多丢失一秒的数据;always 虽然足够可靠,但是会严重拉低性能;no 会让 AOF 文件刷盘的时机脱离 Redis 的控制,并不推荐。

AOF触发机制

开启 AOF 不代表就可以高枕无忧了,因为 AOF 是日志追加的形式,意味着随着不断运行,AOF 日志会越来越大。AOF 日志文件膨胀会带来两个问题:

  • AOF 文件大小超过文件系统的限制会发生错误
  • AOF 文件太大会影响数据恢复效率

所以,Redis 会对 AOF 文件重写手动与自动两种方式:

  • 手动:
            你可以通过bgrewriteaof命令手动触发重写。
  • 自动:
            也可以配置当条件满足时自动触发重写,条件配置如下:
            auto-aof-rewrite-percentage:AOF 文件的增长比例,默认增长为原来的一倍大小就开始重写
            auto-aof-rewrite-min-size:允许 AOF 重写的文件最小值

 为什么重写可以缩小 AOF 文件呢?因为可以把多条命令合并成一条命令,AOF 只需要记录 Key 最新的 Value 即可,而不用记录修改的历史记录(比如多次set值,只留下最后一次的)。

 AOF混合持久化(RDB前导)

最后是aof-use-rdb-preamble参数,它是 Redis4 才开始支持的混合持久化机制,开启后 AOF 重写时将会在 AOF 文件的前半部分先写入全量的 RDB 数据,再把增量 AOF 日志追加在后半部分,同时兼顾了性能和可靠性,建议开启。

② RESP 协议

  • *代表数组,后面跟着数组长度
  • $代表字符串,后面跟着长度

示例 

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

③ ReWrite重写缩减体积

此时我们执行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博客

你可能感兴趣的:(redis,redis,RDB,AOF,持久化,ReWrite)