RDB

作者: 简书徐小耳 | 来源:发表于2018-12-06 22:10 被阅读0次

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条件十分满足

RDB文件结构

image.png
  • 文件中大写的是常量,小写单词标识变量或者数据
  • 程序遇到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所记录出的校验和进行对比,以此来判断文件是否损坏。

当有多个database不为空的时候,RDB文件如下

image.png

每个RDB文件中的数据结构内部如下

  • 遇到db_number 我们会执行select操作 切换到这个数据库


    image.png
  • 真正完整的RDB文件 如下


    image.png
  • key_value_pairs分为带过期时间和不带过期时间

image.png image.png
  • 其中type类型如下,代表一种对象类型或者底层编码


    image.png
  • expiretime_ms 告诉程序 我们读入的是毫秒为单位的过期时间,ms代表一个以毫秒为单位的unix时间戳

相关文章

网友评论

      本文标题:RDB

      本文链接:https://www.haomeiwen.com/subject/nrqocqtx.html