Redis持久化
Redis官方提供了两种持久化方法。
- 快照(Snapshot)
- AOF(Append Only File)只追加日志文件
快照(Snapshot)
1.特点
这种方式是将某一时刻
的所有数据写入磁盘,保存的文件以.rdb
格式存储。因此这种方式也可称为RDB方式
。这也是Redis默认开启的持久化方式
。
2.快照生成方式
- 客户端方式:BGSAVE和SAVE指令。
- 服务器配置自动触发。
a) BGSAVE
当收到客户端的BGSAVE指令时,Redis会调用fork函数来创建一个子进程,然后子进程负责将快照写入磁盘,父进程则继续处理客户端的指令请求。
fork:是一个用于创建子进程的函数。当一个进程调用fork创建一个子进程时,底层操作系统将会创建一个该进程的副本,在刚开始时父子进程共享内存,直到父进程或子进程第一次对内存进行写操作之后,被写入的内存的共享结束。
b) SAVE
当收到客户端的SAVE指令时,Redis主进程负责将快照写入磁盘,期间将不响应任何客户端指令(阻塞
)。
c) 服务器配置
通过在redis.conf
配置文件中配置save
选项,Redis会在save选项条件满足时自动触发一次BGSAVE指令。如果设置了多个save选项,那么当任意一个选项满足时,都会触发一次BGSAVE指令。
d) SHUTDOWN指令
当收到客户端的SHUTDOWN指令时,Redis会执行一个SAVE指令。执行完成后关闭服务器。
AOF(Append Only File)只追加日志文件
1.特点
这种方式是将客户端发送的所有写命令
记录到日志文件中,AOF持久化会将被执行的写命令追加到AOF日志文件的末尾,以此来记录数据的变化。因此,只要从头到尾执行一次AOF中的所有指令,就可以恢复AOF文件记录的数据。
2.开启AOF持久化
a) 修改配置文件
将配置文件中的appendonly
选项改为yes
。
可以修改
appendfilename
选项指定生成的文件名称。以.aof
结尾。
3.日志追加频率
-
always【谨慎使用】
每个写命令都会同步写入到磁盘,严重降低Redis速度。
-
everysec【推荐】【默认】
每秒执行一次将多个写命令同步写入到磁盘。可以保证最多丢失一秒内产生的数据。
-
no【不推荐】
完全由操作系统决定何时同步,不会对任何Redis性能带来任何影响。会丢失不定量的数据。
4.修改日志同步频率
修改配置文件中的appendfsync
选项,选项值为前面三个值中的一个。
AOF文件的重写
1.AOF带来的问题
持久化文件会随着写指令的增加而变得越来越大。例如调用incr num
100次,文件中保存了100条指令,其实99条是多余的,因为要恢复数据库的状态只需执行一条set num 100
就够了。为了压缩AOF持久化文件,Redis提供了AOF的重写
机制。
2.AOF重写
用来一定程度上减小AOF文件的体积。
3.触发重写方式
-
客户端指令
执行
BGREWRITEAOF
命令,不会阻塞Redis。 -
服务器配置自动触发
修改配置文件中的
auto-aof-rewrite-percentage
和auto-aof-rewrite-min-size
选项。如果配置
auto-aof-rewrite-percentage
为100,auto-aof-rewrite-min-size
为64mb,那么当AOF文件大于64mb,并且AOF文件的体积比上一次重写后体积大了100%时,会自动触发重写。
4.重写原理
重写AOF时,并没有读取旧的AOF文件,而是将内存中的数据用命令的方式重写了一个新的AOF文件替换旧的AOF文件。
重写流程:
- Redis调用fork,子进程根据内存中的数据快照,往临时文件中写入重建数据库状态的命令。
- 父进程继续处理客户端请求,除了将写命令追加到原来的文件中,同时将其缓存起来。这样可以保证子进程如果重写失败不会出现问题。
- 当子进程写入完成后通知父进程,父进程就将缓存中的命令写入到临时文件中。
- 父进程将临时文件替换旧的AOF文件并重命名,后续的命令追加到新的AOF文件中。
总结
两种持久化方式既可以单独使用,也可以同时使用,也可以都不使用。
无论使用AOF还是快照持久化机制,将数据写到硬盘都是必要的,除了持久化之外,用户还应该对持久化生成的文件进行备份,增加安全性。