redis官方提供了两种持久化方式
-
快照(snapshot),也叫做rdb持久化
-
AOF,只追加日志文件
一、rdb方式实现持久化
在指定的时间间隔内将内存中的数据集快照写入到磁盘中,保存的文件是以rdb结尾。也就是行话讲的快照(Snapshot),当redis宕机重启时他会直接将快照文件读取进内存中,实现数据恢复。这也是redis默认开启的持久化方式。
1、rdb文件生成方式(快照生成方式)
- 手动输入BGSAVE或者SAVE命令
- 修改配置文件实现自动触发
1.1、使用BGSAVE命令生成rdb文件(快照)
在客户端输入bgsave命令,当redis收到这条命令后会调用fork创建一个子进程。这个子进程相当于父进程的副本。然后子进程会将所有数据写入到一个临时文件中,当持久化的过程结束后。就会用这个临时文件替换上一次的持久化文件(rdb文件)(这个技术称为写时复制技术)。这整个过程中,持久化全由子进程操作,而父进程继续处理其他命令。这种方式性能高,但是最后一次持久化时数据可能丢失。
1.2、使用SAVE命令生成rdb文件(快照)
他的操作与bgsave类似,但不会创建子进程,持久化操作由主进程完成。在这个过程中,其他命令会进入阻塞,当持久化完成后,redis才会处理其他命令。
BGSAVE和SAVE的比较图
bgsave是异步进行的
可以通过lastsave获取最后一次成功执行快照的时间
2、修改配置文件实现自动触发(redis.conf)
当满足任意一个条件时,则会进行一次持久化操作。即自动执行一次bgsave命令
3、shutdown命令生成快照
当redis收到shutdown命令时,会自动执行一个save命令。阻塞所有客户端,不在执行客户端发送的命令,并在save命令执行完毕后关闭服务。
二、AOF实现持久化(默认不开启)
aof,以日志的形式记录每一个写操作,然后把这些命令追加到aof文件中。当redis重启时,他会读取aof文件,把里面记录的所有命令执行一遍,以实现数据恢复。
1、在redis.conf文件中开启aof
因为我的redis版本是7.0,所以一些默认生成的配置有些不一样,请看图:
通过注释可以知道,开启aof后。如果appendfilename的值为appendonly.aof,那么会生成三个派生文件。同时他们的会存放在appendonlydir文件夹中。这个文件夹的默认位置与redis-server文件在一起。
2、如果rdb和aof同时开启,那么redis启动时默认读取aof文件来恢复数据
3、aof文件修复
如果aof文件出现损坏,此时连接redis会出现连接失败,redis服务也未能开启
此时可以使用修复工具对损坏的aof文件进行修复
../redis-check-aof --fix aof文件名
../代表我的redis-check-aof所在的目录
此时redis可以正常启动并用客户端连接
4、aof同步频率设置
- appendfsync always
及时同步:客户端每进行一次写操作,那么就会redis就会把这一次操作记录到aof中。如果1000个客户端同时发送1次写操作,那么redis就会进行1000次同步。这样虽然能把损失降到最少,但这种操作由于要对硬盘进行大量的写操作,所以redis处理速度会受硬盘性能限制。
由于这种同步频率会不断写入小数据,可能会引发严重的写入放大问题。会将硬盘的使用寿命大幅减少,特别是昂贵的固态硬盘,要谨慎使用这种同步频率。
- appendfsync sverysec(redis默认使用的同步频率)
每秒执行一次:如果客户端发送了1000次写入命令,那么不会像always一样来一次写一次,进行1000次同步命令到aof中。而是等到1秒后一次性把这1000个写入命令同步到aof文件中。这样不仅提高了性能,而且最多损失一秒内的数据。
- appendfsync no
redis不主动进行同步,而是把同步时机交给操作系统来决定什么时候进行同步。这种同步不会对redis性能产生影响,但是系统崩溃时会丢失不定量的数据。并且如果用户硬盘写入操作不够快的话,当缓冲区等待写入硬盘的数据填满时,redis会进入阻塞状态,导致redis处理命令的速度下降。
5、redis的aof文件过大问题解决
通过重写机制可以解决aof文件过大的问题
1、通过客户端手动进行重写,输入BGREWRITEAOF命令进行重写
2、redis.conf配置自动触发重写
auto-aof-rewrite-percentage 100:
100表示,文件大小必须是上次重写后文件大小的100%(也就是增加了1倍)
auto-aof-rewrite-min-size 64mb:
64MB表示文件最小要达到64MB
同时满足以上两种条件才会触发重写:以上是redis重写的默认配置,只有当aof文件的大小是上次重写后文件大小的一倍且大于或等于64MB才会触发重写。
例如AOF文件大小为70MB,重写后大小为50MB。那么下一次重写的触发条件:50MB的两倍且大于64MB,也就是至少达到100MB才会触发重写
6、重写的原理
用一个新的aof文件去替换旧的aof文件
流程:
当手动输入bgrewriteaof命令或者自动触发了这个命令时:
1:redis通过fork创建一个子进程,子进程根据当前数据库的状态生成一个快照,然后把快照中的数据以命令的方式写入到一个临时文件中
2:redis正在向临时文件中写入命令,此时父进程继续处理客户端发送过来的其他命令。此时会把这些新发送过来的写命令继续追加到旧的aof文件中,同时把这些新的写命令缓存起来
3:当子进程把所有命令写入到了临时文件中,就会通知父进程,父进程就会把他缓存的那些命令也写入到临时文件中
4、当父进程也写入完成后,就会用这个临时文件去替换旧的aof文件。那些新来的写入命令也会追加到这个新的aof文件中
以上笔记是根据b站up主:编程不良人和尚硅谷综合起来做的,前者讲的更细点