第 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 命令的时间
服务器成功执行一次数据库修改命令之后就对 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 部分
不带过期时间的键值对
TYPE KEY VALUE TYPE:1 字节value:字符串对象,同上襦的 String 类型
带过期时间的键值对
EXPIRETIME_MS MS TYPE KEY VALUE EXPIRETIME_MS:1 字节,告知程序即将读入的是毫秒为单位的过期时间 ms:8 字节的带符号整数,毫秒为单位为 UNIX 时间戳10.3.3 value 编码
1.字符串对象:REDIS_RDB_TYPE_STRINGvalue 保存的为字符串对象,编码有 REDIS_ENCODING_INT 或者 REDIS_ENCODING_RAW
REDIS_ENCODING_INT
长度不超过 32 位的整数
ENCODING 可以是 REDIS_RDB_ENC_INT8、REDIS_RDB_ENC_INT16、REDIS_RDB_ENC_INT32 代表使用几位来保存整数值 integer
REDIS_ENCODING_RAW
字符串对象
压缩与不压缩保存
小于等于 20 字节,原样保存
大于 20 字节,压缩之后再保存
在服务器打开 RDB 文件压缩功能进行的
否则总是无压缩保存
无压缩
压缩
REDIS_RDB_ENC_LZF:常量,表示字符串被 LZF 算法压缩了,程序会对后面三个字段使用解压缩 compressed_len:压缩之后的长度 origin_len:压缩之前的长度 compressed_string:压缩之后的字符串 2.列表对象:REDIS_RDB_TYPE_LIST
value 保存的是 REDIS_ENCODING_LINKEDLIST 编码的列表对象
list_length:列表长度,列表保存了多少个项
item:列表的列表项,每个列表项都是字符串对象
包含长度与实际值3.集合对象:REDIS_RDB_TYPE_SET
REDIS_ENCODING_HT
set_size:集合大小
elem:字符串对象
包含长度与实际值4.哈希表对象:REDIS_RDB_TYPE_HASH
REDIS_ENCODING_HT
键与值相邻排列
5.有序集合对象:REDIS_RDB_TYPE_ZSETREDIS_ENCODING_SKIPLIST
成员与分值紧挨,分值为 double 浮点数,在 double、字符串中互相转换
6.INTSET 编码集合:REDIS_RDB_TYPE_INTSET整数集合与字符串互相转换
7.ZIPLIST 编码的列表、哈希表或者有序集合REDIS_RDB_TYPE_LIST_ZIPLIST
REDIS_RDB_TYPE_HASH_ZIPLIST
REDIS_RDB_TYPE_ZSET_ZIPLIST
压缩列表
压缩列表转换字符串
字符串保存到 RDB
字符串转换压缩列表
根据 TYPE 设置类型
REDIS_RDB_TYPE_LIST_ZIPLIST:列表 REDIS_RDB_TYPE_HASH_ZIPLIST:哈希表 REDIS_RDB_TYPE_ZSET_ZIPLIST:有序集合Redis设计与实现 第 10 章 RDB 持久化
标签:czc 功能 属性 包含 否则 流程 对象 src 不同的
查看更多关于Redis设计与实现 第 10 章 RDB 持久化的详细内容...