RDB:
由命令SAVE和BGSAVE 可以实现RDB操作
- save会阻塞redis服务进程直到RDB文件创建完毕
- bgsave 会创建一个子进程,由子进程创建RDB文件
- 具体的创建工作由函数rdbsave完成
- redis不需要配置命令即可自动载入RDB文件,只要redis检测到RDB文件的存在
- 因为AOF 的更新频率比RDB高,所以如果服务器开启了AOF持久化功能,服务器会优先使用AOF文件来还原数据库状态
-
只有在AOF持久化功能处于关闭状态时候,才使用RDB文件来还原数据库状态。
image.png - 在redis执行BGSAVE命令期间 客户端在发送SAVE命令会被拒绝,(防止父子进程同时执行造成竞争)
- 在redis执行BGSAVE命令期间 客户端在发送BGSAVE命令会被拒绝,(防止父子进程同时执行造成竞争)
- BGREWIRTEAOF(AOF重写)和BGSAVE两个命令页不能同时执行,虽然两者没有竞争 但是同时操作 会导致大量的磁盘写
- 如果BGSAVE正在执行,此时发生AOF重写命令会等到BGSAVE命令执行完成 才执行
- 如果AOF 重写在执行,此时在执行BGSAVE会被拒绝
- 在载入RDB过程会,redis会一直阻塞
因为BGSAVE 不会阻塞主进程,索引redis 通过配置save选项来实现每隔一段时间进行BGSAVE
- save选项可以设置多个保存条件,只要一个满足就执行
,比如save 900 1 就是900秒内对数据库进行了至少一次的修改就执行 -
save条件保存在saveparam,saveparam内部元素就是 seconds(秒),change(修改数)
image.png
- dirty计数器和lastsave属性
- dirty计数器记录上一次save和bgsave之后这个服务器所有数据库的进行了修改
- lastsave属性unix时间戳,记录了服务器上一次成功save命令或者bgsave时间
- redis的周期性操作函数serverCron(我们定期删除过期key也是这个函数)就是检测这个save条件十分满足
image.pngRDB文件结构
- 文件中大写的是常量,小写单词标识变量或者数据
- 程序遇到REDIS开头的文件就是RDB文件,然后就载入这个文件。
- RDB文件是二进制数据,所以我们用R E D I S五个字符来代表魔数,而不是带
\0
结尾符号比如SDS - db_version长度为4字节,他的值是一个字符串表示整数,这个整数记录了RDB文件版本号。
- databases部分包含部分包含着零个或任意多个数据库,如果数据库都为空,那这个部分也为空,长度为0字节。
- 服务器的数据库状态为非空,那这个部分也为非空,数据量不同那么这部分的长度页不同
- EOF常量的长度为1字节,标志着RDB文件正文内容的结束
- check_sum 是一个8字节长字节的无符号整数,保存着一个校验和,校验和是通过对REDIS,db_version,databases,EOF四个部分的内容计算得出的。
- 服务器在载入RDB文件时,会将载入数据所计算出的校验和与checksum所记录出的校验和进行对比,以此来判断文件是否损坏。
image.png当有多个database不为空的时候,RDB文件如下
每个RDB文件中的数据结构内部如下
-
遇到db_number 我们会执行select操作 切换到这个数据库
image.png -
真正完整的RDB文件 如下
image.png -
key_value_pairs分为带过期时间和不带过期时间
-
其中type类型如下,代表一种对象类型或者底层编码
image.png -
expiretime_ms 告诉程序 我们读入的是毫秒为单位的过期时间,ms代表一个以毫秒为单位的unix时间戳
网友评论