AOF方式进行数据恢复时,是逐一执行AOF日志命令,如果日志文件非常大,恢复过程将会很缓慢。那么,如何实现快速恢复呢?今天就来聊聊Redis的持久化方法:RDB内存快照。
所谓内存快照,就是内存中的数据在某一时刻的状态记录。Redis生成内存快照时,就是将某一时刻的状态记录以文件的形式写入磁盘。这个文件,就是RDB文件。
Redis生成RDB文件有两种方式
save:在主线程中执行,会导致阻塞;
bgsave:fork一个子进程,专门用于写入 RDB 文件,避免了主线程的阻塞,这也是 Redis RDB 文件生成的默认配置。
快照的优势
Redis快照是以字节的形式将内存数据保存到RDB文件中,而AOF日志记录的是写命令,快照恢复数据速度更快。
RDB文件相比AOF占用的空间更小;
如果创建RDB文件时出现了错误,Redis不会将它用于替换原来的文件,所以出错时不会影响到之前保存的版本。
快照的缺点
如果硬件机器或系统出现故障,Redis会丢失全部数据。
如果内存数据过多,fork子进程占用的内存也会过大,耗费的时间也会增多。
快照配置方式
在配置文件中配置类似下面的命令
save 900 1 900秒内,有1条写入,则生成快照
save 300 10 // 如果300秒内有10次写入,则生成快照
save 60 10000 如果60秒内有10000次写入,则生成快照
快照生成过程
Redis复制一份主线程的副本(子进程);
主线程继续接收并处理客户端命令,而子进程开始将内存中的数据写入硬盘中的临时文件;
当子进程写入完所有数据后,会用该临时文件替换旧的RDB文件,生成快照操作完成。
快照是否阻塞主线程?
save命令会阻塞主线程。用户发送shutdown命令,系统会先执行save命令,待生成快照后关闭服务器。用户也可以手动执行save命令生成快照。
bgsave不会阻塞主线程。bgsave子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。Redis快照采用写时复制技术(Copy-On-Write, COW),如果此时主线程要修改一块数据,那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。
Redis多久生成一次快照?
快照的频率如果太低,两次快照间一旦宕机,就可能有比较多的数据丢失。如果频率太高,又会产生额外开销。
Redis 4.0 之后,为了解决这个问题,引入了新的持久化模式,混合持久化,将 RDB 的文件和局部增量的 AOF 文件相结合。RDB 可以使用相隔较长的时间保存策略,AOF 不需要是全量日志,只需要保存前一次 RDB 存储开始到这段时间增量 AOF 日志即可,一般来说,这个日志量是非常小的。
这样一来,快照不用很频繁地执行,这就避免了频繁 fork 对主线程的影响。而且,AOF 日志也只用记录两次快照间的操作,也就是说,不需要记录所有操作了,因此,就不会出现文件过大的情况了,也可以避免AOF重写开销。




