Redis设实 - 10 RDB持久化

《Redis设计与实现 黄建宏 著》第10章
该书基于Redis2.9,即Redis3.0开发版编写

服务器中的非空数据库及其键值对统称为数据库状态
持久化操作可将数据库状态保存到文件
RDB持久化可手动执行,也可根据服务器配置选项定期执行

2个生成RDB文件命令

SAVE,阻塞Redis服务器进程,直到RDB文件创建完毕为止,期间不处理任何命令请求
BGSAVE,派生出一个子进程,子进程创建RDB文件,期间服务器进程(父进程)继续处理命令请求

载入持久化文件

因AOF文件通常比RDB文件的更新频率高,故:若服务器开启了AOF持久化功能,则优先使用AOF文件还原数据库状态,否则使用RDB文件还原数据库状态
载入RDB文件的过程是阻塞的
Redis设实 - 10 RDB持久化
Redis设实 - 10 RDB持久化

持久化命令执行时服务器状态

BGSAVE命令执行期间,SAVE命令会被服务器拒绝执行,以避免产生竞争条件(执行两个rdbSave调用)
BGSAVE命令执行期间,BGSAVE命令会被服务器拒绝执行,原因同上
BGSAVE命令执行期间,BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕之后执行
BGREWRITEAOF命令执行期间,BGSAVE命令会被服务器拒绝执行

自动执行BGSAVE命令

服务器配置的save选项可设置多个保存条件,服务器每隔100毫秒检查一次,任意一个条件被满足,便会执行BGSAVE命令
默认save选项设置(间隔秒数 修改数):
save 900 1
save 300 10
save 60 10000

RDB保存条件数据结构

typedef struct redisServer{
// ...
// 记录RDB保存条件的数组
saveparam *saveparams;
// 修改计数器,上一次成功执行SAVE或BGSAVE后数据库状态的修改次数
long long dirty;
// 上一次成功执行SAVE或BGSAVE的时间,UNIX时间戳
time_t lastsave;
// ...
}redisServer;
typedef struct saveparam{
// 间隔秒数
time_t seconds;
// 修改数
int changes;
}saveparam;

RDB文件结构

Redis设实 - 10 RDB持久化
RDB文件保存二进制数据
REDIS,长度5字节,常量,保存“REDIS”5个字符,用以快速检查所载入的文件是否为RDB文件,相当于魔数
db_version,长度4字节,记录RDB文件版本号
databases,包含着0个或任意多个数据库,具体内容见下文
EOF,长度1字节,常量,标示RDB文件正文内容结束
check_sum,长度8字节,无符号整数,保存校验和,校验和由REDIS、db_version、databases、EOF4个部分计算得出

database结构
Redis设实 - 10 RDB持久化
SELECTDB,长度1字节,常量,标示后续是数据库号码
db_number,保存数据库号码,根据号码大小不同,长度可是1字节、2字节或5字节
key_value_pairs,保存键值对数据,若键带有过期时间,则过期时间也会保存在一起

key_value_pairs结构
Redis设实 - 10 RDB持久化
Redis设实 - 10 RDB持久化
EXPIRETIME_MS,长度1字节,常量,标示后续是以毫秒为单位的过期时间
ms,长度8字节,带符号整数,记录以毫秒为单位的UNIX时间戳(过期时间)
TYPE,长度1字节,不固定常量,记录value类型
key,键
value,值,不同类型结构、长度有所不同