redis的持久化主要包括以下几种
- RDB
- AOF
- 混合持久化
RDB
说明
RDB是将某一时刻的内存快照,以二进制的方式写入到磁盘文件中。
触发方式
- 手动触发
- 自动触发
手动触发
手动触发持久化的操作有2个命令:save 和 bgsave ,这两个命令的主要区别是:是否会阻塞主线程的运行
save
手动执行save命令,会触发redis的RDB持久化,此时,会阻塞redis主线程,直到持久化结束后,才能恢复响应其他客户端的命令。
执行前,查看当前rdb文件的状态
执行后,查看rdb文件的状态,可以发现,我们dump.rdb文件的更新时间发生了变更,表名save命令成功触发了持久化。
bgsave
和save命令的主要区别是,bgsave会fork一个子线程来执行持久化,执行持久化的过程不会阻塞主线程,主线程可以响应客户端的其他操作命令,但是fork子线程的过程是阻塞式的(过程很短暂)。所以bgsave命令相比较于save命令更适合手动触发持久化。
自动触发
RDB持久化自动触发有以下几种方式
save m n
在 m 秒时间内,有n个key发生了变化,就会触发持久化过程。其中m 和 n在redis的配置文件中可配置,如果有多个配置的话,只要满足其中一个就会触发持久化。默认有以下三个配置
save 900 1
save 300 10
save 60 1000
flushall
flush命令用于清空Redis的数据库,在生产环境下一定要禁止使用,当redis执行了flushall命令后,会触发自动持久化,将RDB文件清空
主从复制
在Redis的主从复制中,当从节点开始执行全量同步时,主节点会执行bgsave命令,并将生成的rdb文件发送给从节点,该过程会自动触发redis的RDB持久化
RDB文件的优缺点
优点
- RDB文件是二进制数据,占用存储更少,更紧凑,适合作为备份文件。
- 更适合于灾后数据恢复,它是一个紧凑的文件,可以更快的传输到远程服务器进行Redis的数据恢复
- 与AOF的方式相比,RDB文件可以更快的进行数据恢复并重启。
- RDB文件可以更快的提高Redis的运行效率,因为每次持久化,Redis主线程都会fork一个子线程进行持久化操作,Redis主线程并不会被阻塞
缺点
- RDB方式只能保存某个时间间隔内的数据,如果中途Redis服务意外挂了,在上一次进行RDB时间之后发生的数据变更就会丢失。
AOF
说明
Append Only File ,AOF可以把每个Redis每个键值对操作都记录到文件中。
配置
redis默认是关闭aof持久化的,如果需要开启的话,需要修改配置文件(redis.conf),如下所示
appendonly yes
触发方式
自动触发
redis提供了三种配置来触发aof持久化
- always
每条redis操作命令都会写入磁盘,因此最多会丢失一条数据 - everysec
每秒钟写入一次,因此最多会丢失一秒钟的数据 - no
不设置写入磁盘的规则,由操作系统控制何时写入,LINUX默认30秒写入一次。
以上配置可以在redis.conf文件中配置
appendfsync always
## appendfsync everysec
## appendfsync no
手动触发
在客户端执行命令 bgrewriteaof 可以手动触发AOF持久化
下图可以看到,当我们执行bgrewriteaof时,appendonly.aof的最后更新时间变更了。
AOF重写
AOF是通过记录每一次redis的命令来持久化的,随着运行时间的延长,AOF文件会越来越大,这样 不仅增加了存储压力,也会导致redis重启时间越来越长,redis提供了AOF重写的机制来解决此问题,
触发条件
触发AOF重写需要同时满足两个条件,这两个条件可以在redis配置文件中配置,分别是:
- auto-aof-rewrite-min-size
允许AOF重写的最小文件容量,默认是64mb。 - auto-aof-rewrite-percentage
AOF文件重写的大小比例,默认是100,也就是100%,当前 AOF 文件大小相对于上一次重写后的 AOF 文件大小的增长百分比阈值达到100%时,才会启动AOF文件的重写
AOF重写流程
AOF文件重写是生成一个全新的文件,并把当前数据的最少操作命令保存到新文件上,当把所有的数据都保存到新文件之后,交换2个文件,并把最新的持久化操作命令追加到最新的文件上面。
- Redis 主进程 调用 fork() 创建 子进程,子进程拥有与父进程相同的内存数据快照(写时复制机制,Copy-On-Write)
- 子进程遍历当前数据库的所有键值对,根据数据类型生成对应的 Redis 命令,写入临时文件(如 temp-rewriteaof-bg-进程ID.aof)
- 主进程 继续处理客户端请求,新写入的命令会:
追加到 原 AOF 缓冲区(写入旧 AOF 文件)。
同时追加到 AOF 重写缓冲区(用于同步到新 AOF 文件) - 子进程完成所有数据写入后,向主进程发送信号;主进程将 AOF 重写缓冲区 中的数据追加到新 AOF 文件末尾,确保数据完整性
- 主进程用新 AOF 文件 原子替换 旧文件(通过 rename 系统调用),后续命令写入新文件
持久化文件加载规则
- 如果只开启了AOF持久化,Redis启动时只会加载AOF文件进行数据恢复
- 如果只开启了RDB持久化,Redis启动时只会加载RDB文件进行数据恢复
- 如果同时开启了AOF持久化和RDB持久化,Redis启动时只会加载RDB文件进行数据恢复
优缺点
优点
- AOF持久化保存的数据更加完整,AOF提供了三种保存策略,从数据的安全性和性能考虑,选择每秒保存一次是一个不错的选择,这也是默认配置策略,意外情况下,最多只会丢失1秒的数据。
- AOF采用的是追加写的方式,所以不会出现文件损坏的情况,即使有意外情况,导致最后操作的持久化数据写入了一半,也可以通过redis-check-aof工具修复
- AOF持久化文件存储的是Redis键值对操作命令,非常容易理解,即使使用了flushall命令删除了所有的键值信息,也可以通过aof文件,删除最后的flushall命令来恢复之前误删的数据。
缺点
- 由于存储的是redis命令,所有体积会比RDB文件要大。
- Redis负载比较高的情况下,AOF的性能会不如RDB
- RDB存储的是二进制文件的数据,AOF存储的是redis键值对命令,数据恢复时,RDB文件会更快
混合持久化
混合持久化 结合RDB和AOF的优点,在Redis4.0版本引入,5.0及以后版本默认开启
混合持久化的触发,和AOF文件重写深度绑定,当AOF文件重写时,Redis会先通过子进程生成当前内存数据的RDB快照,写入新的AOF文件头部,主进程将重写期间新的命令追加到新的AOF文件的后面。
混合持久化的加载流程
- 判断当前是否开启了AOF持久化,未开启执行加载RDB文件流程
- 判断appendonly.only文件是否存在,存在则继续执行后续流程
- 判断AOF文件开头是否是RDB文件的格式,若是,先加载RDB内容再加载剩余的AOF内容
- 判断AOF文件开头不是RDB文件的格式,按照纯AOF文件的方式加载整个文件
Redis如何判断AOF文件开头是RDB格式的
通过关键字REDIS判断的,RDB文件的开头一定是REDIS关键字开头的,如下所示。
[root@iZbp15gubfasb9bg4glzjqZ bin]# cat appendonly.aof
REDIS0009� redis-ver6.2.6�
�edis-bits�@�ctime�=9hused-mem�`Oaof-preamble���test2test2�B",����Y*2
$6
SELECT
$1
0
*3
$3
set
$5
test3
$5
test3
优缺点
优点
结合了RDB和AOF各自的优点,开头是RDB格式,加载更快,体积更小。并且降低了大量数据丢失的风险
缺点
- AOF文件中增加了RDB格式,可读性变差
- 兼容性变差,如果开启混合持久化,就不能使用在Redis4.0 之前的版本了