redis持久化机制
redis是基于内存存储的数据库,如果redis 重启或者操作系统崩溃或者关机,那么内存中的数据将会被清空。所以为了确保数据安全性和可靠性,需要将内存中的数据持久化到磁盘上,持久化还可用于备份、数据恢复和迁移等。
redis主要提供两种持久化机制:
- RDB(Redis DataBase)持久化
- AOF(Append Only File)持久化
一、RDB持久化
1、RDB持久化原理:
RDB(Redis DataBase)持久化是一种基于快照的持久化方式。在指定的时间间隔内,当符合一定条件时,redis会自动将内存中所有数据以二进制方式生成一份副本并存储在硬盘上,这个RDB文件可以用于数据恢复或备份。RDB持久化提供了较高的数据压缩率和快速的数据加载速度,但可能存在一定程度的数据丢失,当redis重启时,redis会读取之前生成的RDB文件来恢复数据(默认名为dump.rdb,可通过修改redis.conf中的dbfilename来更改,还可配置rdbcompression来指定是否压缩,压缩会损耗性能,不压缩文件过大,默认是压缩的)
2、RDB持久化触发方式:
- 手动触发:使用SAVE或BGSAVE命令。SAVE是同步命令,由redis工作线程执行,执行过程中会阻塞客户端请求。BGSAVE是异步命令,主进程会forks一个子进程(fork过程中redis是阻塞的,不相应客户端请求),进行异步持久化,持久化过程中主进程仍然可以处理其他请求。
- 自动触发:在配置文件redis.conf中设置触发条件
- 关闭Redis时触发:Redis在关闭服务时会自动触发一次RDB持久化
- 主从同步时触发:当从节点连接到主节点时,向主节点发送SYNC命令时,主节点会触发一次RDB持久化,并将生成的RDB文件发送给从节点进行同步
3、下面我们手动异步触发一下持久化,首先执行命令如下:
bgsave
Background saving started # 子进程创建成功,它会去完成持久化

先设置了key,然后手动触发,查看redis日志信息,日志文件的位置可通过如下命令获取:
config get logfile # 查看redis日志位置

从上图可以看出,首先开始持久化,到最后持久化完成。
通过如下命令查看rdb文件的位置(可通过修改redis.conf中的dir来改变):
config get dir

进入此路径下查看rdb文件是否存在,如图:

4、自动触发持久化
自动触发主要是配置文件中的save模块,如下:

上图中为redis.conf的默认配置,表示900s内有1次写操作或300s内有10次写操作或60s内有1000次写操作即触发持久化
5、恢复
重启redis后,可以看到日志中加载了RDB文件来恢复数据,如图:

登录redis命令行,查看之前创建的key是否存在,如图:

因为我们做了持久化,因此数据还是存在,否则重启后数据会丢失,因为数据是保存在内容中
6、RDB持久化优缺点
优点:
- 高性能:通过fork子进程进行RDB操作,主进程无需进行磁盘IO,保证了Redis的高性能
- 快速恢复:RDB文件包含了某一时刻的完整数据快照,可以快速恢复数据
- 更小的存储空间:RDB文件经过压缩,占用较小的磁盘空间
缺点:
- RDB无法做到完全的实时持久化,会存在数据丢失
- fork子进程的时候,会影响性能
二、AOF持久化
1、AOF持久化原理
AOF(Append Only File)持久化是一种基于日志的持久化方式。Redis将所有的写操作命令追加到一个AOF文件中。当Redis重新启动时,可以通过重放AOF文件中的命令来恢复数据,开启AOF虽然会影响一定性能,不过可以接受。
redis将每一条写命令以redis通讯协议添加至缓冲区aof_buf,这样的好处在于在大量写请求情况下,采用缓冲区暂存一部分命令随后根据策略一次性写入磁盘,这样可以减少磁盘的I/O次数,提高性能。
2、开启AOF并配置同步策略
appendonly yes # 默认是没开启的

同步策略(redis.conf中appendfsync来配置):
- no:不使用fsync方法同步,而是交给操作系统write函数去执行同步操作,在linux操作系统中大约每30秒执行一次 sync。缓冲区数据同步不可控,并且在大量的写操作下,aof_buf缓冲区会堆积会越来越严重,一旦redis出现故障,数据丢失严重,整体不可控
- always:表示每次有写操作都调用fsync方法强制内核将数据写入到aof文件。这种情况下由于每次写命令都写到了文件中, 虽然数据比较安全,但是因为每次写操作都会同步到AOF文件中,所以在性能上会有影响,同时由于频繁的IO操作,硬盘的使用寿命会降低
- everysec:数据写入aof_buf后将调用操作系统write写入文件,并使用fsync每秒一次从内核刷新到磁盘。这是折中的方案,兼顾性能和数据安全,所以redis默认推荐使用该配置

3、AOF文件重写
当开启AOF时,随着时间推移,AOF文件会越来越大,redis提出一种重写的策略来缓解数据存储和恢复压力,通过fork子进程,由子进程完成相应的操作,同样的在fork子进程简短的时间内,redis是阻塞的(此时客户端无法写入)
在redis.conf文件中进行配置,控制AOF重写的触发条件,如下:
# 指定在执行BGSAVE或BGREWRITEAOF命令时是否禁用AOF文件同步。默认为yes,表示禁用同步。
no-appendfsync-on-rewrite no
# AOF文件大小增长到原始大小的百分比时进行重写,默认为100,表示AOF文件大小增长到原始大小的两倍时进行重写
auto-aof-rewrite-percentage 100
# 指定进行AOF重写的最小AOF文件大小。默认为64mb
auto-aof-rewrite-min-size 64mb #
AOF重写会创建一个新的AOF文件,只包含当前内存中数据的最小命令集。在重写过程中,Redis会继续将新的写操作追加到原始AOF文件中。当重写完成后,新的AOF文件将替换原始AOF文件。
4、AOF重写触发条件
- 自动触发:就是上面的auto-aof-rewrite-min-size和auto-aof-rewrite-percentage
- 手动触发:执行命令bgrewriteaof
我们手动执行一下bgrewriteaof,如图:

查看redis日志,已经重写成功,如图:

5、AOF持久化优缺点
优点:
- 更高的数据安全性:根据同步策略的选择,AOF持久化可以保证较高的数据安全性
- 更好的容错性:即使AOF文件存在部分损坏,仍可以恢复大部分数据
缺点:
- 较大的存储空间:与RDB持久化相比,AOF文件通常较大,占用较多磁盘空间
- 数据加载速度较慢:由于需要重放AOF文件中的命令,数据恢复速度相对较慢
三、混合持久化
1、混合持久化原理
Redis首先使用RDB持久化将内存中的数据快照存储到磁盘上,然后再使用AOF持久化将所有新的写操作追加到AOF文件中。这样做的好处是:
- 在系统崩溃时,可以通过RDB文件进行快速恢复,而AOF文件可以用于恢复最近的修改
- RDB持久化可以减少AOF文件的大小,从而减少磁盘空间的使用
2、开启混合持久化
主要将AOF开启那么就是开启了混合持久化,RDB默认是开启的,AOF默认关闭
3、混合持久化过程
首先fork一个子进程,生成全量的rdb快照,放在appendonly.aof 文件头部。然后,接下来将aof缓冲区的增量命令以aof方式写入文件尾,每次恢复数据时,首先从RDB部分恢复,然后执行aof
4、数据恢复
启动redis后依然优先加载aof文件,aof文件加载可能有两种情况:
- aof文件开头是rdb的格式, 先加载 rdb内容再加载剩余的 aof
- aof文件开头不是rdb的格式,直接以aof格式加载整个文件
5、混合持久化应用场景
- 确保数据完整性,不能容忍数据丢失
- 快速恢复数据,以减少故障恢复时间
- 提高主从同步效率,以保证高可用性和负载均衡
6、混合持久化优缺点
优点:
- 高数据安全性:结合了AOF持久化的高数据安全性
- 快速恢复:利用RDB持久化的快速数据恢复速度
- 提高redis从服务器节点同步效率:利用RDB文件进行快速同步
缺点:
- 占用过多存储空间:需要同时维护RDB文件和AOF文件


