RDB文件的创建与载入
SAVE指令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求
BGSAVE命令会派生出一个子进程,由它负责创建RDB文件,服务器进程(父进程)继续处理命令请求。
def SAVE():
#创建RDB文件
rdbSave()
def BGSAVE():
# 创建子进程
pid=fork()
if pid == 0:
# 子进程负责创建RDB文件
rdbSave()
# 完成之后向父进程发送信号
signal_parent()
elif pid>0:
# 父进程继续处理命令请求,并通过轮询等待子进程的信号
handle_request_and_wait_signal()
else:
# 处理出错情况
handle_fork_error()
自动间隔性保存
服务器每隔一段时间自动执行一次BGSAVE
命令,可以设置多个保存条件,只要任意一个条件被满足,服务器就会执行BGSAVE
指令
save 900 1
save 300 10
save 60 10000
服务器在900秒内进行了至少1次修改
服务器在300秒内进行了至少10次修改
服务器在60秒内进行了至少10000次修改
设置保存条件
struct redisServer
{
struct saveparam * saveparams;
long long dirty; //距离上一次成功执行BGSAVE之后,进行修改的次数
time_t lastsave; //上一次成功执行BGSAVE的时间
};
struct saveparam
{
time_t seconds;
int changes;
}
检查保存条件是否满足
默认每隔100ms执行一次serverCron()
def serverCron():
# 遍历所有保存条件
for saveparam in server.saveparams:
save_interval=unixtime_now()-server.lastsave
#如果数据库状态的修改次数超过条件所设置的次数
#并且距离上次保存的时间超过条件所设置的时间
#那么执行保存操作
if server.dirty >= saveparam.changes and save_interval>saveparam.seconds:
BGSAVE()
RDB文件结构
概览
- REDIS,通过这五个字符,程序可以在载入文件时,快速检查所载入的文件是否是RDB文件
- db_version,记录了版本号
- databases,包含任意个数据库以及他们的键值对数据。
- EOF,标志着RDB文件正文内容的结束
- check_sum,校验和,检查RDB文件是否有出错或损坏的情况
databases
每个非空数据库保存三部分:
- SELECTDB 常量,说明接下来会读取一个数据库号码
- db_number,读入后,调用SELECT指令,进行数据库切换,使得之后读入的键值对可以载入到正确的数据库之中
- key_value_pairs,保存了数据库中的所有键值对数据。包含过期时间。
key_value_pairs
- TYPE记录了value的类型,代表了一种对象类型或底层编码。
- key总是一个字符串对象
- value根据TYPE的指令保存相应类型的内容
- EXPIRETIME_MS常量,代表之后会读取一个以毫秒为单位的过期时间
- ms,保存键值对的过期时间