Redis 04章——持久化
一、总体介绍
- 官网地址:https://redis.io/docs/manual/persistence/
- 为什么需要持久化
二、持化双雄
(1)一图
(2)RDB(Redis DataBase)
2.2.1官网介绍
2.2.2是什么
- 在指定的时间间隔,执行数据集的时间点快照
- 实现类似照片记录效果的方式,就是把某一时刻的数据和状态以文件的形式写到磁盘上,也就是快照。这样一来即使故障宕机,快照文件也不会丢失,数据的可靠性也就得到了保证
- 这个快照文件就称为RDB文件(dump.rdb)其中,RDB就是Redis DataBase的缩写
2.2.3能干嘛
- 在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的snapshot内存快照,它恢复时再将硬盘快照文件直接读回到内存里
- Redis的数据都在内存中,保存备份时它执行的是全量快照,也就是说,把内存中的所有数据都记录到磁盘中,一锅端
- RDB保存的是dump.rdb文件
2.2.4案例演示
(1)需求说明
(2)配置文件(6 vs 7)
- Redis6.0.16及以下
- Redis6.2以及Redis-7.0.0
(3)操作步骤
一、自动触发
- Redis7版本,按照redis.conf里配置的 save <seconds> <changes>
- 本次案例5秒2次修改
- 修改dump文件保存路径(.表示redis7.conf所在路径)
- 修改dump文件名称
- 触发备份
- 第一种情况:5秒内修改两次
- 第二种情况:修改满两次,就触发备份
- 注意:5秒内只修改一次,不会触发备份!
- 第一种情况:5秒内修改两次
- 如何恢复
- 将备份文件(dump.rdb)移动到 Redis 安装目录并启动服务即可(意思就是,我们每次都是从.rdb中读取的文件)
- 备份成功后故意用flushdb清空redis,看看是否可以恢复数据(执行flushall/flushdb命令也会产生dump.rdb文件,但里面是空的,无意义)
- 我们把/myredis/dumpfiles里面所有的.rdb文件全部删除,确保只留下了dump6379.rdb.bak,记得把名字改一下(把.bak去掉)
- 然后此时重启服务器
- 物理恢复,一定要将服务产生的RDB文件备份一份,然后分机隔离,避免生产上物理损坏后备份文件也挂了
- 注意一:当我们flushdb,会自动触发备份
- 当我们关闭服务器,重启,会发现确实被清空了,因为从dump6379.rdb读的
- 注意二:当我们shutdown关机,也会自动触发备份
二、手动触发
- Redis提供了两个命令来生成RDB文件,分别是save和bgsave
- save:
- 作用:在主程序中执行会阻塞当前redis服务器,直到持久化工作完成执行save命令期间,Redis不能处理其他命令,线上禁止使用
- 案例演示:我们先把dump6379.rdb删除,然后在5分钟内只修改一次,可以发现是没有触发备份的,但是我们手动save,就会有.rdb文件了
- bgsave:
- redis会在后台异步进行快照操作,不阻塞快照同时还可以相应客户端请求,该触发方式会fork一个子进程由子进程复制持久化过程
- 官网说明:
- Redis会使用bgsave对当前内存中的所有数据做快照,这个操作是子进程在后台完成的,这就允许主进程同时可以修改数据
- fork是什么?
- 各位熟悉的:
- 操作系统角度:在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,尽量避免膨胀
- 各位熟悉的:
- 案例:
- lastsave:
- 可以通过lastsave命令获取最后一次成功执行快照的时间
- 举例:
2.2.5优势
(1)官网说明

(2)小总结
- 适合大规模的数据恢复
- 按照业务定时备份
- 对数据完整性和一致性要求不高
- RDB文件在内存中的加载速度要比AOF快很多
2.2.6劣势
(1)官网说明

(2)小总结
- 在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失从当前至最近一次快照期间的数据,快照之间的数据会丢失
- 内存数据的全量同步,如果数据量太大会导致IO严重影响服务器性能
- RDB依赖于主进程的fork,在更大的数据集中,这可能会导致服务请求的瞬间延迟。fork的时候内存中的数据被克隆了一份,大致2倍的膨胀性,需要考虑
(3)数据丢失案例
- 正常录入数据
- kill -9模拟意外丢失宕机
- redis重启恢复,查看数据是否丢失
2.2.7如何检查修复dump.rdb文件
2.2.8哪些情况会触发RDB快照
- 配置文件中默认的快照配置
- 手动save/bgsave命令
- 执行flushdb/fulshall命令也会产生dump.rdb文件,但是也会将命令记录到dump.rdb文件中,恢复后依旧是空,无意义
- 执行shutdown且没有设置开启AOF持久化
- 主从复制时,主节点自动触发
2.2.9如何禁用快照
- 动态所有停止RDB保存规则的方法:redis-cli config set value ""
- 手动修改配置文件
2.2.10RDB优化配置项详解(配置文件SNAPSHOTTING模块)
- save <seconds> <changes>:配置快照保存条件
- dir:配置快照保存目录地址
- dbfilename:配置快照的文件名
- stop-writes-on-bgsave-error:默认yes,如果配置成no,表示不在乎数据不一致或者有其他的手段发现和控制这种不一致,那么在快照写入失败时,也能确保redis继续接受新的请求
- rdbcompression:默认yes,对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,Redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能
- rdbchecksum:默认yes,在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
-
rdb-del-sync-files:在没有持久化的情况下删除复制中使用的RDB文件。默认情况下no,此选项是禁用的
2.2.11小总结
(3)AOF(Append Only File)
2.3.1官网介绍
2.3.2是什么
- 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但是不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
- 默认情况下,redis是没有开启AOF的。开启AOF功能需要设置配置:appendonly yes
2.3.3能干嘛
2.3.4AOF保存的是appendonly.aof文件
2.3.5AOF持久化工作流程
2.3.6AOF缓冲区三种写回策略
(1)三种写回策略
(2)三种写回策略小结update
2.3.7AOF案例演示和说明
(1)配置文件说明(6 vs 7)
一、如何开启aof(修改配置文件)

二、使用默认写回策略,每秒钟
三、aof文件-保存路径
- redis6
- redis7
则appendonly.aof会存放在dir + appenddirname
四、aof文件-保存名称
- redis6:有且仅有一个
- redis7(一个文件由三部分组成):
- Redis7.0 Multi Part AOF的设计:
- 官网说明
- 从1到3
- Redis7.0config中对应的配置项
- 官网说明
(2)正常恢复
一、启动:设置yes,修改默认的appendonly no,改为yes
二、写操作继续,生成aof文件到指定的目录
可以看到,现在是dir ./的情况下,新生成的dump6379.rdb已经不在dumpfiles里了
三、恢复
- 先把rdb相关的都删掉
- 把appendonlydir拷贝一份
- flushdb后发现又生成了一个rdb文件,然后把它删除
- shutdown后发现又生成了一个rdb文件,然后把它删除
- 注意:flushdb也是一个写操作,所以当我们重启服务器,读出来是空的
- 我们把原来的appendonlydir删除,把appendonlydir.bak改名为appendonlydir,还要顺便把dump6379删了
- 重启服务器
- 可以发现,当我们进行写操作的时候,.incr的大小是会发生变化的
(3)异常恢复
- 每一秒钟写入一次,内容才写了一小半,没有写完整。。突然,redis挂了,导致aof文件错误
- 故意乱写正常的AOF文件,模拟网络闪断文件写error
- 重启Redis之后就会进行AOF文件的载入,发现启动都不行
- 异常修复命令:redis-check-aof --fix进行修复
- 启动后OK
2.3.8优势
- 更好的保护数据不丢失、性能高、可做紧急恢复
- 如图:
2.3.9劣势
- 相同数据集的数据而言AOF文件要远大于RDB文件,恢复速度慢于RDB
- AOF运行效率要慢于RDB,每秒同步策略效率较好,不同步效率和RDB相同
2.3.10AOF重写机制
(1)是什么
- 由于AOF持久化是Redis不断将写命令记录到 AOF 文件中,随着Redis不断的进行,AOF 的文件会越来越大,文件越大,占用服务器内存越大以及 AOF 恢复要求时间越长
- 为了解决这个问题,Redis新增了重写机制,当AOF文件的大小超过所设定的峰值时,Redis就会自动启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,或者可以手动使用命令 bgrewriteaof 来重新
- 一句话:启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集
(2)触发机制
一、官网默认配置
- 如图:
- 注意 ,同时满足,且的关系才会触发:
- 根据上次重写后的aof大小,判断当前aof大小是不是增长了1倍
- 重写时满足文件的大小
二、自动触发
满足配置文件中的选项后,Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时
三、手动触发
客户端向服务器发送bgrewriteaof命令
(3)案例说明
一、需求说明
二、需求验证
启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集
三、步骤
- 前期配置准备:
- 开启aof(在配置文件中)
- 默认峰值修改为1K
- 关闭混合,设置为no
- 删除之前的全部aof和rdb,清除干扰项
- 开启aof(在配置文件中)
- 自动触发案例01:
- 完成上述正确配置,重启redis服务器,执行 set k1 v1 查看aof文件是否正常
- 查看aof三大 配置文件(appendonly.aof.1.base.aof;appendonly.aof.1.incr.aof;appendonly.aof.manifest)
- k1不停11111111暴涨
-
重写触发(在上面的基础上再set一次)
- 完成上述正确配置,重启redis服务器,执行 set k1 v1 查看aof文件是否正常
- 手动触发案例02:
- 结论:
(4)重写原理
2.3.11AOF优化配置项详解
2.3.12小总结
三、RDB-AOF混合持久化
(1)官网建议
(2)rdb vs aof
3.2.1问题
(1)可否共存?可以
(2)如果共存听谁的?AOF优先加载
3.2.2官网文档
3.2.3数据恢复顺序和加载流程
(3)你怎么选?用哪个?
- RDB持久化方式能够在指定的时间间隔对你的数据进行快照存储
- AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾
(4)同时开启两种持久化方式
- 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整
- RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。但是作者也不建议只使用AOF方式备份,因为RDB更适合用于备份数据库(AOF在不断的变化不好备份),留着RDB作为一个万一的手段
(5)推荐方式
- 结合了RDB和AOF的优点,既能快速加载又能避免丢失过多的数据
- 方法: