Redis设计与实现 第 10 章 RDB 持久化
时间:2022-03-07 04:09
第 10 章 RDB 持久化
数据库状态:服务器中的非空数据库以及它们的键值对统称为数据库状态
Redis 提供 RDB 持久化功能,将内存中的数据库状态保存到磁盘中,避免数据意外丢失
RDB 文件是一个经过压缩的二进制文件,还可以通过该文件还原生成 RDB 文件时的数据库状态
10.1 RDB 文件的创建与载入
SAVE、BGSAVE命令生成 RDB 文件
SAVE 命令会阻塞 Redis 服务器进程,直到文件创建完毕,阻塞期间无法处理任何请求
BGSAVE 命令会派生子进程,由子进程负责创建 RDB 文件,服务器父进程继续处理命令请求
创建 RDB 文件的实际工作由 rdb.c/rdbSave 完成,两个命令会以不同的方式调用此函数
RDB 文件的载入工作在服务器启动时自动执行的,只要检测到 RDB 文件存在,自动载入 RDB 文件
AOF文件更新频率通常比 RDB 文件的更新频率高,所以:
- 如果服务器开启了 AOF 持久化功能,服务器会优先使用 AOF 文件来还原数据库状态
- 只有在 AOF 持久化功能关闭才会使用 RDB 文件来还原状态
10.1.1 SAVE 命令执行时的服务器状态
阻塞,只有命令执行完成后客户端的命令才会被处理
10.1.2 BGSAVE 命令执行时的服务器状态
服务器可以继续处理命令请求,但有些区别
- SAVE 命令被拒绝
- BGSAVE 命令也被拒绝
- BGREWRITEAOF 不能同时执行
- BGSAVE 在执行,被延迟到前者完成后
- 正在执行,BGSAVE 被拒绝
- 性能方面考虑,两个子进程同时执行大量写入操作
10.1.3 RDB 文件载入时服务器的状态
阻塞
10.2 自动间隔性保存
设置服务器配置 save 选项,让服务器妹隔一段时间自动执行一次BGSAVE 选项
save 900 1
save 300 10
save 60 10000
在 900 s 内,对数据库进行了至少一次修改
同理
三个条件满足一个,BGSAVE 命令就会执行
10.2.1 设置保存条件
save 900 1
save 300 10
save 60 10000
以上为默认设置,如果没有指定配置参数或者传入启动参数方式
服务器会根据 save 选项设置 redisServer.saveparams 属性
默认情况如下:
10.2.2 dirty 计数器和 lastsave 属性
- dirty计数器
- 记录距离上一次执行 SAVE 命令或者 BGSAVE 命令之后服务器对数据库进行了多少次修改
- lastsave
- UNIX 时间戳
- 记录了服务器上一次成功执行 SAVE 命令或 BGSAVE 命令的时间
- UNIX 时间戳
服务器成功执行一次数据库修改命令之后就对 dirty 计数器进行更新
10.2.3 检查保存条件是否满足
serverCron 默认每隔 100 ms 执行一次,对运行的服务器维护,其中一项工作就是检查设置的保存条件是否满足,是则执行 BGSAVE 命令
10.3 RDB 文件结构
完整的 RDB 文件结构如下:
常量:全大写单词
变量和数据:全小写单词
- REDIS:5 字节,保存 “REDIS” 5 个字符,方便程序快速分辨为 RDB 文件
RDB 为二进制数据,“REDIS” 保存的不是 c 字符串
-
db_version:4 字节,为字符串表示的常数, REB 版本号
-
database
-
零个或多个数据库,以及数据库中的键值对数据
-
如果数据库状态为空,此处也为空,长度 0 字节
-
数据库状态非空,根据情况不同,长度不同
-
-
EOF:常量,1 字节,标志 RDB 文件正文内容结束,即所有数据库所有键值对载入完成
-
check_num:8 字节无符号整数,校验和,通过前四个部分计算而来,载入时计算是否与之相同验证文件是否损坏
10.3.1 database 部分
database 可以保存任意多个非空数据库
假设 0 号、3 号数据库非空, RDB 文件如图,database 代表 0 号数据库中的所有键值对
database 0 又可以再细分
-
SELECTDB:1 字节,表明接下来读入的是数据库号码
-
db_number:数据库号码,可以为1 3 5 字节
-
key_value_pairs:数据库中的所有键值对数据,如果有过期时间也会保存在一起
10.3.2 key_value_pairs 部分
不带过期时间的键值对
带过期时间的键值对
|
---|