Redis(三)——RDB、AOF
RDB
什么是RDB
这个RDB其实就是Redis他自己的默认持久化策略,因为我们知道Redis是一个内存数据库,那么就存在服务器宕机或者停电等不可抗力导致的数据丢失,相对于mysql来说停电最多丢失一部分数据,而对于Redis来说就是毁灭性的,所以需要按照一定的规则对Redis数据库的数据进行保存,也就是我们说的快照,等到真出问题了那么可以使用快照进行恢复。

我们的快照文件是经过压缩的二进制文件哦。而且RDB保存的快照文件是,当前redis数据库的全量文件,也就是所有的key和value哦。

我们的手动触发就是开一个子线程去把当前的快照保存成一个临时文件,保存成功后就把旧的rdb进行覆盖,那这两个命令有什么区别呢?区别就是是否阻塞。另外可以使用lastsave查看上一次报错快照的时间。
特性 | SAVE | BGSAVE | 关键差异 |
|---|---|---|---|
执行方式 | 同步阻塞 | 异步非阻塞 | 最核心区别 |
性能影响 | 高(阻塞所有操作) | 低(后台执行) | 对业务影响程度 |
适用场景 | 维护、调试 | 生产环境 | 使用场景完全不同 |
数据一致性 | 强一致性 | 最终一致性 | 数据状态保证 |
推荐程度 | ❌ 不推荐生产使用 | ✅ 推荐生产使用 | 生产环境选择 |
我们Redis6的默认规则如下:(在redis.conf)
# RDB持久化配置# 1. 自动保存条件(格式:seconds changes)
save 900 1 # 900秒内至少1个键改变
save 300 10 # 300秒内至少10个键改变
save 60 10000 # 60秒内至少10000个键改变# 2. RDB文件名称
dbfilename dump.rdb# 3. RDB文件目录
dir /var/lib/redis# 4. BGSAVE错误时停止写入
stop-writes-on-bgsave-error yes# 5. RDB文件压缩
rdbcompression yes# 6. RDB文件校验
rdbchecksum yes# 7. 是否开启RDB持久化
# 注释所有save行可禁用自动RDB
# save ""
或者使用命令redis-cli config set save ""在Redis7的时候对RDB的保存逻辑进行了改变:所以不同的版本对于RDB的默认策略是不同的,当然这个策略我们也是可以修改的。
save 3600 1 # 一个小时内至少1个键改变
save 300 1 # 300秒内至少100个键改变
save 60 10000 # 300秒内至少10000个键改变 如何恢复
其实这个很简单,和mysql根本就不同,因为我们的Redis每次重启都从conf文件中配置的rdb路径读取.rbd文件进行恢复,所以根本就不需要操作了?那就不是了,因为我们上面的触发快照保存的方式有很多,我们手动关闭redis服务、flushdb清空数据库都会生成快照然后覆盖我们之前的rbd文件,所以有些时候数据还是会丢失的,那怎么办?通常情况下要么从集群中其他从机拿取rbd文件,要么就是写一个脚步或者定时任务,把rdb文件保存到其他文件目录或者其他机器上,这样才能最大程度保证数据的可恢复性。
另外我们的rdb文件也可能损耗了,就比如我们rdb文件复制一半停电了,那么就可能导致文件的损害,那么可以使用官方的工具进行检查和修复:
# 基本语法
redis-check-rdb [选项] <rdb文件路径># 常用选项
redis-check-rdb --help
Usage: redis-check-rdb <rdb-file-name>--fix # 尝试修复文件--no-error # 忽略错误继续检查# 常见安装位置:这个是我们redis官方工具的常见地址,如redis-cli
# - 源码编译:/usr/local/bin/redis-check-rdb
# - 包管理器:/usr/bin/redis-check-rdb
# - Docker容器:/usr/local/bin/redis-check-rdb优缺点
优点很明显就是1.全量的备份,2.子线程进行备份不影响主线程提供服务,3.恢复速度快,因为保持的就是对应的数据结构的二进制文件,不需要解析,4.复制恢复速度快,因为满足条件或者其他情况出发备份,都是顺序复制和读写。
缺点也很明显,1个就是数据丢失的可能性高,因为我们的触发条件不可能覆盖所有的情况,2.就是自动覆盖,执行一个删库rdb文件也更新了,根本不能直接使用rdb进行恢复,3.子线程导致主线程阻塞,在系统资源耗尽的情况下复制,主线程会被阻塞。
AOF
什么是AOF
这个就是Redis的另一种持久化方案,但是他是默认关闭的,AOF是以日志的形式,其实和我们mysq的binlog优点类似,只记录增删改不记录查操作(清空数据库操作也会被记录),如果把AOF、RDB都打开的情况下,redis启动会先读取AOF日志进行回放,如果没有AOF文件,然后再读取RDB文件。也就是AOF比RDB优先级高,因为AOF的数据丢失率更低。
但是我们可以使用混合模式aof-use-rdb-preamble这个配置默认是开的,这个打开后RDB负责数据,AOF负责增量,其实就是redis7的模式。
这个是AOF相关的配置表格:
配置项 | 默认值 | 作用 | 生产建议 |
|---|---|---|---|
appendonly |
| 是否开启AOF |
|
appendfilename |
| AOF文件名 | 按业务命名 |
appendfsync |
| 数据同步策略 |
|
dir |
| AOF文件目录,redis6之前和RDB 在同一个目录,7之后在RDB同一 个目录下的appendfilename/目录 下,appendfilename配置是什么 就是什么 | 独立数据目录 |
auto-aof-rewrite-percentage |
| 重写触发条件 |
|
auto-aof-rewrite-min-size |
| 最小重写大小 |
|
aof-load-truncated |
| 加载截断文件 |
|
aof-use-rdb-preamble |
| 混合持久化 |
|
这个就是AOF的写入逻辑,其中三种刷盘机制和mysql一模一样,都是默认每秒刷盘而且都是后台线程进行刷盘,如果看过主包mysql篇的内容,对这个就很好理解的。

另外就是redis7后AOF文件就不再是一个了,而是分成了三个,一个是base文件:使用紧凑的二进制格式存储的某一个时间点的快照,这样redis重启读aof的时间就快多了,不用把全部的AOF操作读取回放了,二是Incr文件(增量文件):记录Base文件之后的写命令,就是redis启动先读取base文件然后在这个基础上读取incr文件进行回放,三是Manifes:记录所有AOF文件的组织和顺序、告诉Redis启动时按什么顺序加载文件,可以理解为base文件和incr文件的索引。
总结出来的好处就是会比redis6要更快,因为随着操作的增加redis6的AOF会越来越大,那么重启的时候需要的时间也就越多,而redis7是当incr文件增加到一定阈值(最小是64MB)就会重新记录base文件(当前时刻的数据快照),重新记录incr文件。保证redis7启动时的速度。
如何恢复
AOF也和RDB一样,所以redis也为我们提供了工具,其实用法、名称和RDB的差不多。为什么AOF会损害?如果写入AOF的incr文件的时候,写入一半停电不就文件损坏了吗。
# 基本语法
redis-check-aof [选项] <AOF文件路径># 查看帮助
$ redis-check-aof --help
Usage: redis-check-aof [--fix] [--truncate-to-timestamp <timestamp>] <file.aof>选项:--fix 修复AOF文件(截断到最后一个有效命令)--truncate-to-timestamp 截断到指定时间戳(Unix时间戳)-v, --verbose 详细输出模式--version 显示版本信息--help 显示此帮助信息优缺点
优点:一个是基本上不会丢失数据,就算丢失也是1秒钟的数据,因为我们默认的刷盘机制就是1秒,二个是incr是一个文本文件,就算损坏了也很好修复,而且我们也可以修改文本文件,比如fulashall命令被记录后,我们可以删除incr文件中的这个命令,然后重启数据就回恢复。
缺点就是:一个是AOF会越来越大,就算AOF被重写了文件也会比上一次的大,这和jvm的动态内存一样,初始最大内存大小是256mb后面GC后内存大小会被修改变大。二个就是恢复速度慢的问题,因为是命令重放这个没办法的,三个就是系统资源的影响,因为默认都是一秒刷盘持续的I/O操作是很吃系统资源的。
这里再把AOF重写讲清楚吧,这个是redis的配置(6和7都有),要满足两个条件才会重写,当前文件增长率为上一个AOF文件的1倍也就是100%,同时大雨最小文件64mb,才会触发重写。redis7会同时base和incr文件,修改manifest文件,redis6会重写AOF文件。除了这个自动触发我们还可以使用手动触发,使用bgrewiteraof就可以和RDB一样。
# Redis配置参数
auto-aof-rewrite-percentage 100 # 增长百分比阈值
auto-aof-rewrite-min-size 64mb # 最小文件大小这个就是重写后的文件,后缀会逐步递增的,当然这个是redis7,redis6的话文件名是不变的。

纯缓存模式
如果我们把AOF和RDB都关闭,那就是纯缓存模式,没有任何的持久化备份,这个情况下一般都是高并发、高性能的场景下使用,因为持久化备份会消耗一定的系统资源,但是一般情况都会开启持久化,如果不行那就加机器、加钱呗,这个才是万全之策。
总结
本篇主要说的就是Redis的持久化方案。
