我们知道Redis的数据是存在内存中的,那么就会有一个问题,如果突然宕机了或者故障了,Redis的数据就会全部消失了,为了不让数据丢失,我们需要将数据写到磁盘文件里面,这样当机器回复时可以还原数据,RDB就是Redis持久化的方法之一。


RDB持久化既可以手动执行,也可以根据服务器配置自动执行。RDB持久化功能生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成的RDB文件时的数据。


我们可以通过两个命令生成RDB文件,一个是SAVE,一个是BGSAVA。二者的区别是:SAVE命令会阻塞Redis服务器进程,知道RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求。BGSAVE命令则会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程继续处理命令请求。子进程生成RDB文件之后,会向父进程发送信号,父进程继续处理命令请求,并通过轮训等待子进程的信号。


RDB文件的载入是服务器启动时自动执行的,这里没有专门载入RDB文件的命令。值得注意的是:因为AOF文件的更新频率通常比RDB文件更新频率高,所以AOF保存的数据会更新一些,如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件还原数据库状态。只有在AOF持久化功能处于关闭时,服务器才会使用RDB文件还原数据库数据。


自动间隔性保存RDB文件


因为BGSAVE命令可以在不阻塞服务器进程的情况下执行,所以Redis允许用户设置服务器配置的save选项,让服务器每隔一段时间自动执行一次BGSAVE命令。用户可以设置多个保存条件,当其中任意一个条件满足时,服务器就会执行BGSAVE命令。用户可以通过配置文件或者传入启动参数的方式设置save选项,如果没有主动设置,服务器会有默认设置条件。


save 900 1


save 300 10


save 60 10000


这几个属性意味着如果60秒内有10000次修改操作,或者300秒内有10次修改操作,或者900秒内有1次修改操作,服务器就会执行BGSAVE命令。这一配置可以让修改频繁的情况下60秒执行一次备份,不频繁的情况下300秒或者900秒执行一次备份。


那么Redis是如何检查是否达到条件的呢?Redis服务器维持了一个dirty计数器以及lastsave属性,dirty计数器记录上次成功执行SAVE或者BGSAVE命令后,服务器对数据库进行了多少次修改,lastsave属性是一个时间戳,记录了服务器上一次成功执行SAVE命令或者BGSAVE命令的时间。


当服务器成功执行一个数据库修改命令之后,程序会对dirty计数器进行更新,命令修改了多少次数据库,dirty计数器的值就增加多少。


Redis服务器周期性操作函数serverCron函数(又提到了这个函数),默认100ms执行一次,它的其中一项工作就是检查save选项设置的保存条件是否满足,如果满足的话就执行BGSAVE命令。实现起来比较简单


遍历所有设置的条件,计算距离上次执行保存操作过了多少秒,计算修改次数dirty是否大于任意一个条件,如果条件满足执行BGSAVE命令。


生成RDB持久化文件之后,就涉及到RDB文件的载入,这里不详细介绍RDB文件的构成了,简单说下RDB文件主要包括REDIS标识,版本号,数据库键值对,EOF,校验合等数据,比较好理解。值得注意的是,如果键有过期时间,RDB文件会保存键的过期时间。