Redis的RDB文件是RDB持久化功能生成的一个压缩二进制文件
RDB生成
创建RDB文件由rdb.c/rdbSave函数完成。RDB持久化通过两种方式生成RDB文件
1.手动执行,例如SAVE、BGSAVE命令
2.根据服务器配置选项定期执行,服务器每隔一段时间自动执行BGSAVE命令
SAVE命令执行时阻塞Redis进程。BGSAVE命令会派生一个子进程,然后由子进程负责创建RDB文件,父进程继续处理其它请求。在服务器定时同步期间,客户端返送的手动执行命令会被拒绝,避免父进程和子进程同时执行rdbSave函数产生竞争,因为两个进程同时执行大量磁盘写入操作。
RDB定期执行原理
Redis通过服务器配置save选项,让服务器每隔一段时间自动执行一次BGSAVE命令。
例如:save 900 10 为服务器在900秒之内,对数据库至少进行了10次修改就会自动执行。
struct redisServer{
//记录保存条件的数组
struct saveparam *saveparam;
//修改计数器,记录距离上一次执行RDB持久化后,服务器对数据进行了多少次修改(插入、删除、更新)
long long dirty;
//上一次执行保存的时间,UNIX时间戳,上一次成功RDB持久化的时间
time_t lastsave;
//...
}
saveparam 是一个数组,数组中每一个元素都是一个saveparam结构体
struct saveparam{
//秒数
time_t seconds;
//修改数
int changes;
}
Redis服务器有个周期性操作函数serverCron,默认是每100毫秒执行一次,该函数其中一项工作就是检查save选项保存的条件是否已经满足,如果满足就执行BGSAVE函数。程序会遍历saveparams数组里所有的元素条件,只要有一个满足,就会执行BGSAVE命令。
RDB载入
Redis并没有专门用于载入RDB文件的命令,只能在Redis服务器启动时自动载入。在Redis服务器载入RDB文件期间,服务一直处于阻塞状态,直到载入工作完成。载入工作由rdb.c/rdbLoad函数完成。
只有满足同时以下条件,Redis才会载入RDB文件
- RDB文件存在
- AOF持久化功能处于关闭状态
RDB文件结构
- REDIS,文件开头长度为5个字节,保存“REDIS”五个字符,用于程序载入时检查是否为RDB文件
- db_version,长度4字节的字符串整数,记录RDB文件的版本号
- database:保存各个数据库的所有键值对数据,如果数据库是空的,那这部分内容也是空的
- EOF:1字节的常量,表示RDB文件正文结束,当程序读到这里时代表所有键值对已加载完毕
- check_sum:8字节的无符号整数,可以理解为是前面四部分的hash值,程序载入RDB文件时,会根据前面四部分内容计算一个值来和check_sum比较,用于校验RDB文件是否有损坏。