redis 快照持久化RDB和AOF

一,redis快照持久化RDB介绍

RDB(Redis DataBase)是将 Redis 内存中的数据进行 Snaptshot 快照存储在磁盘内,是 Redis 的默认持久化
方案。使用 RDB 持久化默认有三种策略,该持久化策略在 redis.conf 中可配置,会以一段时间内有指定次数据
修改的规则触发快照动作,快照文件名为 dump.rdb,该文件默认使用 LZF 压缩算法 。每当 Redis 服务重启的
时候会从该文件中加载数据进内存。

RDB 持久化除了可以根据配置中的策略触发,也可以手动触发,使用 save 和 bgsave 命令即可。这两个命
令的区别的 save 会阻塞服务器进程,在进行 save 的过程中,服务器不能处理任何请求,而 bgsave 会通过一个
子进程在后台处理 rdb 持久化。事实上 save 和 bgsave 调用的都是 rdbSave 函数,因此 Redis 不允许 save 和
bgsave 同时运行,这也是为了避免出现竞争导致 rdb 文件数据不准确

bgsave 操作使用 CopyOnWrite 机制进行写时复制,是由一个子进程将内存中的最新数据遍历写入临时文
件,此时父进程仍旧处理客户端的操作,当子进程操作完毕后再将该临时文件重命名为 dump.rdb 替换掉原来的
dump.rdb 文件,因此无论 bgsave 是否成功,dump.rdb 都不会受到影响。

另外在主从全量同步、debug reload 以及 shutdown 的情况下也会触发 RDB 数据持久化

1.1 RDB原理
save 原理

bgsave 原理

1.2 RDB的优点

RDB 是一种表示某个即时点的 Redis 数据的紧凑文件。RDB 文件适合用于备份。例如,你可能想要每小时
归档最近 24 小时的 RDB 文件,每天保存近 30 天的 RDB 快照。这允许你很容易的恢复不同版本的数据集
以容灾。

RDB 非常适合于灾难恢复,作为一个紧凑的单一文件,可以被传输到远程的数据中心。

RDB 最大化了 Redis 的性能,因为 Redis 父进程持久化时唯一需要做的是启动(fork)一个子进程,由子进程

完成所有剩余工作。父进程实例不需要执行像磁盘 IO 这样的操作。
RDB 在重启保存了大数据集的实例时比 AOF 要快

1.3 RDB的缺点

当你需要在 Redis 停止工作(例如停电)时最小化数据丢失,RDB 可能不太好。你可以配置不同的保存点(save
point)来保存 RDB 文件(例如,至少 5 分钟和对数据集 100 次写之后,但是你可以有多个保存点)。然而,你
通常每隔 5 分钟或更久创建一个 RDB 快照,所以一旦 Redis 因为任何原因没有正确关闭而停止工作,你就
得做好最近几分钟数据丢失的准备了。

RDB 需要经常调用 fork()子进程来持久化到磁盘。如果数据集很大的话,fork()比较耗时,结果就是,当数据
集非常大并且 CPU 性能不够强大的话,Redis 会停止服务客户端几毫秒甚至一秒。AOF 也需要 fork(),但是
你可以调整多久频率重写日志而不会有损(trade-off)持久性(durability)。

1.4 RDB优缺点总结

优点:速度快,适合于用作备份,主从复制也是基于 RDB 持久化功能实现的。
缺点:会有数据丢失、导致服务停止几秒

1.5RDB触发机制

在配置文件中配置触发的条件
900 秒内有一个 key 变化
300 秒内有 10 个 key 变化
60 秒内有 1w 个 key 变化

1.6快照持久化相关配置
[root@redis01 ~]# vim /usr/local/redis/etc/redis.conf

save m n 
# 配置快照(RDB)触发规则,格式:save <seconds> <changes>
# save 900 1 900 秒内后至少有 1 个 key 被改变则做一次快照
# save 300 10 300 秒内后至少有 300 个 key 被改变则做一次快照
# save 60 10000 60 秒内后至少有 10000 个 key 被改变则做一次快照

# 关闭该规则使用 svae “”

dbfilename dump.rdb
# rdb 持久化存储数据库文件名,默认为 dump.rdb

stop-write-on-bgsave-error yes
# yes 代表当使用 bgsave 命令持久化出错时候停止写 RDB 快照文件,no 表明忽略错误继续写文件。

rdbchecksum yes
# 在写入文件和读取文件时是否开启 rdb 文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动。

dir "/etc/redis"
# 数据文件存放目录,rdb 快照文件和 aof 文件都会存放至该目录,请确保有写权限

rdbcompression yes
# 是否开启 RDB 文件压缩,该功能可以节约磁盘空间
1.7停止备份

在配置文件中就设置 save “”或在命令行中 config set save “”。

1.8 手动开始备份

save:会立即生成 dump.rdb,但是会阻塞往 redis 内存中写入数据。
bgsave:后台异步备份。

如果是使用 flushdb 命令,会把之前的快照更新成当前的空状态,所以执行了 flushdb 后更新的快照是没有数据的。

二,save与bgsave对比

命令 save bgsave
io类型 同步 异步
是否阻塞 否(阻塞发生在fork)
优点 不会消耗额外内存 不阻塞客服端命令
缺点 阻塞客服端命令 创建fork,消耗内存

三,AOF介绍

AOF(Append-Only File)记录 Redis 中每次的写命令,类似 mysql 中的 binlog,服务重启时会重新执行 AOF
中的命令将数据恢复到内存中,RDB(按策略持久化)持久化方式记录的粒度不如 AOF(记录每条写命令),因此很
多生产环境都是开启 AOF 持久化。AOF 中记录了操作和数据,在日志文件中追加完成后才会将内存中的数据进
行变更。

3.1 AOF原理
  1. 客户端的请求写命令会被 append 追加到 AOF 缓冲区内;
  2. AOF 缓冲区根据 AOF 持久化策略[always,everysec,no]将操作 sync 同步到磁盘的 AOF 文件中;
  3. AOF 文件大小超过重写策略或手动重写时,会对 AOF 文件 rewrite 重写,压缩 AOF 文件容量;
  4. Redis 服务重启时,会重新 load 加载 AOF 文件中的写操作达到数据恢复的目的;
3.2 AOF配置

开启了 AOF 之后,RDB 就默认不使用了。使用下面的配置开启 AOF 以及策略。(如果使用 AOF,推荐选择
always 方式持久化,否则在高并发场景下,每秒钟会有几万甚至百万条请求,如果使用 everysec 的方式的话,
万一服务器挂了那几万条数据就丢失了)。

# 开启 AOF 持久化
appendonly yes

# AOF 文件名
appendfilename "appendonly.aof"

# AOF 文件存储路径 与 RDB 是同一个参数
dir "/opt/app/redis6/data"

# AOF 策略,一般都是选择第一种[always:每个命令都记录],[everysec:每秒记录一次],[no:看机器的心
情高兴了就记录]
appendfsync always
# appendfsync everysec
# appendfsync no

# aof 文件大小比起上次重写时的大小,增长 100%(配置可以大于 100%)时,触发重写。[假如上次重写后大小为
10MB,当 AOF 文件达到 20MB 时也会再次触发重写,以此类推]
auto-aof-rewrite-percentage 100

# aof 文件大小超过 64MB 时,触发重写
auto-aof-rewrite-min-size 64mb

# 是否在后台写时同步单写,默认值 no(表示需要同步).这里的后台写,表示后台正在重写文件(包括 bgsave
和 bgrewriteaof.bgrewriteaof 网上很多资料都没有涉及到。其实关掉 bgsave 之后,主要的即是 aof 重
写文件了).no 表示新的主进程的 set 操作会被阻塞掉,而 yes 表示新的主进程的 set 不会被阻塞,待整个后
台写完成之后再将这部分 set 操作同步到 aof 文件中。但这可能会存在数据丢失的风险(机率很小),如果对性
能有要求,可以设置为 yes,仅在后台写时会异步处理命令.
no-appendfsync-on-rewrite no

# 指 redis 在恢复时,会忽略最后一条可能存在问题的指令。默认值 yes。即在 aof 写入时,可能存在指令写
错的问题(突然断电,写了一半),这种情况下,yes 会 log 并继续,而 no 会直接恢复失败.
aof-load-truncated
3.3 AOF 持久化策略

AOF 分别有三种备份策略,分别是[always:每个命令都记录],[everysec:每秒记录一次],[no:看机器的心情高兴
了就记录],针对这三种策略给出如下说明。

3.4 AOF持久化策略说明
策略 说明 优点
always 每次执行,都会持久化到 AOF 文件中 不丢失数据
everysec 每秒持久化一次 减少
no 根据服务器性能持久化 全自动
3.5 策略抉择

|命令 |Always| Everysec| no|
|优点 |不丢失数据 |每秒一次 fsync,减少 IO| 不用管,全自动|
|缺点 |IO |开销大| 丢 1 秒钟的数据| 不可控|

3.6 AOF重写

AOF 持久化机制记录每个写命令,当服务重启的时候会复现 AOF 文件中的所有命令,会消耗太多的资源且
重启很慢。因此为了避免 AOF 文件中的写命令太多文件太大,Redis 引入了 AOF 的重写机制来压缩 AOF 文件
体积。AOF 文件重写是把 Redis 进程内的数据转化为写命令同步到新 AOF 文件的过程

3.7 AOF重写配置
配置名 含义
appendonly 开启
auto-aof-rewrite-min-size 触发重写的最小尺寸
auto-aof-rewrite-percentage AOF 文件增长率
aof_current_size AOF 当前尺寸
aof_base_size AOF 上次启动和重写的尺寸(单位:字节)
3.8 AOF重写触发机制

根据配置,AOF 持久化触发机制如下:

  1. aof_current_size > auto-aof-rewrite-min-size
  2. (aof_current_size - aof_base_size) / aof_base_size > auto-aof-rewrite-percentage

    上图就是AOF的工作原理了,感觉自己画的还是比较通俗易懂的哈哈哈

  需要注意的是,在这里子进程把数据转为写指令存入新的AOF文件时,记录的只是每个数据的最后一次写指令,也就是最新的数据,不会记录之前冗余的操作,所以这样会很大程度的缩小AOF的体量,同时,该操作是产生新的AOF文件进行写入,而不是在原有文件上的修改,通过上图也可以看出来。而缓存中叠加到新的aof的操作仍是新增的全部操作,但是这些数据已经很有限,相比之前的一股脑添加,这种机制很好的解决的AOF文件不断增大的问题。

3.9 AOF重写须知

  和RDB一样,如果当前的数据量巨大,那么创建子进程的过程会很耗时。在大数据的处理工作中,文件的删除也是一项比较麻烦的工作。想我们普通的笔记本电脑,删除一个几GB的文件都是一项很耗时的工作,更何况大数据的量级远远大过我们日常使用的数据。所以在替换aof文件时,如果旧的aof很大,删除它也是一个很耗时的过程。当然这并不是aof或者redis的缺点,只是可能会出现的一个客观情况。

四,RDB与AOF抉择

4.1 RDB与AOF比较
命令 RDB AOF
启动优先级
体积
恢复速度
数据安全性 丢数据 根据策略的不同,丢数据的情况也不同
轻重
4.2 RDB与AOF之间的优劣势
1. RDB的优点
  1. 压缩后的二进制文件,适用于备份、全量复制及灾难恢复。
  2. RDB 恢复数据性能优于 AOF 方式
2.RDB的缺点
  1. 无法做到实时持久化,每次都要创建子进程,频繁操作成本过高
  2. 保存后的二进制文件,不同版本直接存在兼容性问题
3.AOF的优点
  1. 以文本形式保存,易读
  2. 记录写操作保证数据不丢失
4.AOF的缺点
  1. 存储所有写操作命令,且文件为文本格式保存,未经压缩,文件体积高。
  2. 恢复数据时重放 AOF 中所有代码,恢复性能弱于 RDB 方式

五,AOF与RDB混合使用

看了上面的 RDB 和 AOF 的介绍后,我们可以发现,使用 RDB 持久化会有数据丢失的风险,但是恢复速度
快,而使用 AOF 持久化可以保证数据完整性,但恢复数据的时候会很慢。于是从 Redis4 之后新增了混合 AOF
和 RDB 的模式,先使用 RDB 进行快照存储,然后使用 AOF 持久化记录所有的写操作,当重写策略满足或手动
触发重写的时候,将最新的数据存储为新的 RDB 记录。这样的话,重启服务的时候会从 RDB 何 AOF 两部分恢
复数据,即保证了数据完整性,又提高了恢复的性能。
开启混合模式后,每当 bgrewriteaof 命令之后会在 AOF 文件中以 RDB 格式写入当前最新的数据,之后的
新的写操作继续以 AOF 的追加形式追加写命令。当 redis 重启的时候,加载 aof 文件进行恢复数据:先加载 rdb
的部分再加载剩余的 aof 部分。

5.1 混合配置
# 修改下面的参数即可开启 AOF,RDB 混合持久化
aof-use-rdb-preamble yes
5.2 混合模式的使用

开启混合持久化模式后,重写之后的 aof 文件里和 rdb 一样存储二进制的快照数据,继续往 redis 中进行写
操作,后续操作在 aof 中仍然是以命令的方式追加。因此重写后 aof 文件由两部分组成,一部分是类似 rdb 的二
进制快照,另一部分是追加的命令文本。

posted @ 2020-12-15 19:21  nick_xm  阅读(201)  评论(0编辑  收藏  举报