Redis 作为内存数据库 , 提供了基础的 RDB 持久化的机制。
RDB文件是一个压缩的二进制文件保存在磁盘之中。
SAVE # 阻塞式创建 RDB文件
BGSAVE # 创建子进程创建 RDB 文件
Redis 启动的时候会自动的加载生成的RDB文件,所以没有显式的load rdb 文件的命令。
当Redis启动的时候,如果开启了AOF持久化功能,会默认载入AOF文件,否则继续载入 RDB 文件。
当开启 BGSAVE 之后, 会开启一个子进程开始持久化,这个过程中,系统不会允许第二个 BGSAVE SAVE 命令的执行,甚至 BGREWRITEAOF 也不被允许, 因为存在多个子进程开始读写IO 和 多个进程开始竞争不是一个很好的选择。
自动间隔保存
save 300 10 # 300秒内修改10次就会开启 bgsave 后台保存
redis 的默认save条件
save 900 1
save 300 10
save 60 10000
每一个save配置选项 ,都会保存在 saveParam 数组中
struct redisServer {
struct saveParam *saveparams;
long long dirty; # 距离上一次save后的数据修改次数
time_t lastsave; # 上一次执行保存的时间
}
那么当修改次数达到配置的上线的时候,如何进行触发?
最直观的我理解应该是 在 dirty 修改的时候去判断保存配置,可能是成本太高。
redis 采取的是一个 serverCron 函数来定期维护系统的状态,包括 saveParam 状态
RDB 文件结构
rdb文件是一个二进制组织结构的文件
- 文件标识: RDB 文件开头是 REDIS 部分,采用 5字节保存 ,标识是一个 RDB 文件
- db_version : 记录一下文件记录的数据库版本 , 长度为 4 字节 ,表示一个字符串表示的整数 比如 ”0006“
- database : 零个或者任意个数据库的数据的内容,如果为空表示0字节 , 每一个数据库由下面几个部分组成:
- selectdb : 一字节 ,表示接下来读取的是数据库号码
- db_number : 保存一个数据库号码
- key_value_pairs : 保存键值对
- EOF: 1 字节的常量,表示正文内容的结束,表示文件已经载入结束了
- check_sum : 8字节长度的无符号整数,保存一个校验和 , 计算一下前面的四个部分的内容。
下面细说一下 key_value_pairs :
在内存中存储的结构中,redis数据基于一个字典存储多个key 和value 的结构;同时使用一个过期字典保存键和过期时间。
但是在 rdb 文件之中,过期时间和真实的键值都同时保存在 key_value_pairs 之中 , 由下面三个方面组成:
-
TYPE : 1字节表示类型 , 表示数据结构类型和存储结构
REDIS_RDB_TYPE_STRING REDIS_RDB_TYPE_LIST REDIS_RDB_TYPE_SET REDIS_RDB_TYPE_ZSET REDIS_RDB_TYPE_HASH REDIS_RDB_TYPE_LIST_ZIPLIST REDIS_RDB_TYPE_SET_INTSET REDIS_RDB_TYPE_ZSET_ZIPLIST REDIS_RDB_TYPE_HASH_ZIPLIST EXPIRETIME_MS
-
KEY
-
VALUE