RDB
我们可以通过一下两个命令来生成RDB文件
- SAVE :会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求
- BGSAVE:BGSAVE会派生出一个子进程,然后由子进程负责RDB文件,服务器进程继续处理命令请求 创建RDB文件的实际工作由rdb.c/rdbSave函数完成
RDB文件加载
RDB 文件的载入工作是在服务器启动时自动执行的,只要redis服务器在启动时检测到RDB文件存在,就会自动载入RDB文件
- 服务器以主服务器模式运行时,未过期的键会被载入到数据库中,而过期键则会被忽略
- 当服务器以从服务器模式运行时,不论是否过期,所有键都会被载入到数据库中。因为主从服务器在进行数据同步的时候,从服务器的数据库就会被清空 因为AOF文件的更新频率通常比RDB文件的更新频率高
- 如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF来还原数据库状态
- 只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据库状态 服务器还原数据库状态的流程图如下图所示
BGSAVE
- BGSAVE命令执行期间会拒绝客户端发来的SAVE命令,避免产生竞争条件
- BGSAVE命令指向期间也会拒绝客户端发来的BGSAVE命令,避免产生竞争条件
- BGWRITEAOF与BGSAVE不能同时运行(该两个命令实际都是由子进程进行工作)
- 如果BGSAVE正在运行,客户端发送的BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕之后执行
- 如果BGREWRITEAOF正在运行,那么客户端发送的BGSAVE命令会被服务器拒绝
RDB文件载入时的服务器状态
服务器在载入RDB文件期间,会一直处于阻塞状态,知道载入工作完成之后
自动间隔性保存
用户可以通过设置服务器的save选项,让服务器每隔一段时间自动执行一次BGSAVE命令 举例,如果我们向服务器提供一下配置: save 900 1 save 300 10 save 60 10000 那么只要满足一下三个条件中的任意一个,BGSAVE命令就会被执行:
- 服务器在900秒之内,对数据库进行1次修改
- 服务器在300秒之内,对数据库进行10次修改
- 服务器在60秒之内,对数据库进行10000次修改
dirty计数器和lastsave属性
通过上图结构我们可以知道服务器还维持着一个dirty计数器和lastsave属性
- dirty计数器:距离上一次成功执行SAVE命令或者BGSAVE命令后,服务器 对数据库进行了多少次修改
- lastsave:记录上一次成功执行SAVE命令或者BGSAVE命令的时间
检查保存条件是否满足
redis的定时任务去检查设置的条件是否满足,该定时任务执行周期是每100ms执行一次。
RDB文件结构
如下图所示
- RDB开头是"REDIS"这五个字符。通过这个字符,程序可以在加载过程中判断载入的文件是否为RDB文件
- db_version记录了RDB的版本号
- database包含着多个数据库的键值对数据
- EOF常量长度为1字节,这个常量标志着RDB文件正文内容的结束。
- check_sum保存着校验和,这个校验和通过REDIS,db_version,database,EOF四个部分的内容进行计算得出的。在载入数据时计算出校验和与check_sum所记录的校验和进行对比,依次来检查RDB文件是否有出错或者损坏的情况
分析RDB文件
我们可以通过od 命令来分析RDB文件,使用od -c dump.rdb打印RDB文件 Redis自带redis-check-dump工具,可以通过该工具对RDB文件进行检查
- [1] [redis设计与实现]