目录
RDB持久化
服务器中的非空数据库以及它们的键值对统称为数据库状态。
因为Redis是内存数据库,它将自己的数据库状态储存在内存里面,所以一旦服务器进程退出,服务器中的数据库状态也会消失不见。
为了解决这个问题,Redis提供了RDB持久化功能,这个功能可以将Redis在内存中的数据库状态保存到磁盘里面,避免数据意外丢失。因此RDB文件是保存在硬盘里面的。
RDB文件的创建与载入
SAVE和BGSAVE可以用于生成RDB文件。
SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求
BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程继续处理命令请求
RDB文件载入工作是在服务器启动时自动执行的,只要Redis服务器在启动时检测到RDB文件存在,它就会自动载入RDB文件。
- 如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据库状态。
- 只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据库状态。
SAVE命令执行时的服务器状态
阻塞
BGSAVE命令执行时的服务器状态
BGSAVE命令执行期间,客户端发送的SAVE命令会被服务器拒绝,服务器禁止SAVE命令和BGSAVE命令同时执行是为了避免父进程(服务器进程)和子进程同时执行两个rdbSave调用,防止产生竞争条件。
在BGSAVE命令执行期间,客户端发送的BGSAVE命令会被服务器拒绝,因为同时执行两个BGSAVE命令也会产生竞争条件
BGSAVE和BGREWRITEAOF两个命令不能同时执行:
- 如果BGSAVE命令正在执行,那么客户端发送的BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕之后执行
- 如果BGREWRITEAOF命令正在执行,那么客户端发送的BGSAV命令会被服务器拒绝
RDB文件载入时的服务器状态
服务器在载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成为止。
自动间隔性保存
满足以下三个条件中任意一个,BGSAVE命令就会自动被执行
- 服务器在15min内,对数据库进行了至少1次修改
- 服务器在5min内,对服务器进行了至少10次修改
- 服务器在1min内,对服务器进行了至少1000次修改
设置保存条件
Dirty计数器和lastsave属性
检查保存条件是否满足
Redis的服务器周期性操作函数serverCron默认每隔100ms就会执行一次,该函数用于对正在运行的服务器进行维护,其中一项工作就是检查save选项所设置的保存条件是否已经满足,如果满足,就会执行BGSAVE
RDB文件结构
REDIS:五字节,保存着“REDIS”五个字符,用于检查是否为RDB文件
db_version:4字节,RDB文件版本号
databases:包含着零个或任意多个数据库,以及数据库中的键值对数据
EOF:1字节,标志RDB文件正文内容结束
check_sum:8字节无符号整数,保存校验和,校验和是前四个部分的内容进行计算得出的。通过在载入数据计算所得出的检验和与check_sum进行对比,以此来检查RDB文件是否出错或者损坏的情况出现。
databases部分
SELECTDB:1字节
db_number:数据库号码。1、2或、5字节
key_calue_pairs:保存数据库中所有键值对数据,如果有过期时间,过期时间也会和键值对保存在一起
key_calue_pairs部分
value编码
- 字符串对象
- 列表对象
- 集合对象
- 哈希表对象
- 有序集合对象
- INSET编码的集合
先将整数集合转换为字符串对象,然后将这个字符串对象保存到RDB文件里面
- ZIPLIST编码的列表、哈希表或者有序集合
- 将压缩列表转换成一个字符串对象
- 将转换所得的字符串对象保存到RDB文件