码迷,mamicode.com
首页 > 数据库 > 详细

Redis设计与实现 第 10 章 RDB 持久化

时间:2021-06-23 16:26:57      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:czc   功能   属性   包含   否则   流程   对象   src   不同的   

第 10 章 RDB 持久化

数据库状态:服务器中的非空数据库以及它们的键值对统称为数据库状态

技术图片

Redis 提供 RDB 持久化功能,将内存中的数据库状态保存到磁盘中,避免数据意外丢失

RDB 文件是一个经过压缩的二进制文件,还可以通过该文件还原生成 RDB 文件时的数据库状态

技术图片

10.1 RDB 文件的创建与载入

SAVE、BGSAVE命令生成 RDB 文件

SAVE 命令会阻塞 Redis 服务器进程,直到文件创建完毕,阻塞期间无法处理任何请求

BGSAVE 命令会派生子进程,由子进程负责创建 RDB 文件,服务器父进程继续处理命令请求

创建 RDB 文件的实际工作由 rdb.c/rdbSave 完成,两个命令会以不同的方式调用此函数

技术图片

RDB 文件的载入工作在服务器启动时自动执行的,只要检测到 RDB 文件存在,自动载入 RDB 文件

AOF文件更新频率通常比 RDB 文件的更新频率高,所以:

  • 如果服务器开启了 AOF 持久化功能,服务器会优先使用 AOF 文件来还原数据库状态
  • 只有在 AOF 持久化功能关闭才会使用 RDB 文件来还原状态

技术图片

10.1.1 SAVE 命令执行时的服务器状态

阻塞,只有命令执行完成后客户端的命令才会被处理

10.1.2 BGSAVE 命令执行时的服务器状态

服务器可以继续处理命令请求,但有些区别

  • SAVE 命令被拒绝
  • BGSAVE 命令也被拒绝
  • BGREWRITEAOF 不能同时执行
    • BGSAVE 在执行,被延迟到前者完成后
    • 正在执行,BGSAVE 被拒绝
    • 性能方面考虑,两个子进程同时执行大量写入操作

10.1.3 RDB 文件载入时服务器的状态

阻塞

10.2 自动间隔性保存

设置服务器配置 save 选项,让服务器妹隔一段时间自动执行一次BGSAVE 选项

save 900 1
save 300 10
save 60 10000

在 900 s 内,对数据库进行了至少一次修改

同理

三个条件满足一个,BGSAVE 命令就会执行

10.2.1 设置保存条件

save 900 1
save 300 10
save 60 10000

以上为默认设置,如果没有指定配置参数或者传入启动参数方式

服务器会根据 save 选项设置 redisServer.saveparams 属性

技术图片

技术图片

默认情况如下:

技术图片

10.2.2 dirty 计数器和 lastsave 属性

  • dirty计数器
    • 记录距离上一次执行 SAVE 命令或者 BGSAVE 命令之后服务器对数据库进行了多少次修改
  • lastsave
    • UNIX 时间戳
      • 记录了服务器上一次成功执行 SAVE 命令或 BGSAVE 命令的时间

技术图片

服务器成功执行一次数据库修改命令之后就对 dirty 计数器进行更新

10.2.3 检查保存条件是否满足

serverCron 默认每隔 100 ms 执行一次,对运行的服务器维护,其中一项工作就是检查设置的保存条件是否满足,是则执行 BGSAVE 命令

技术图片

10.3 RDB 文件结构

完整的 RDB 文件结构如下:

技术图片

常量:全大写单词

变量和数据:全小写单词

  • REDIS:5 字节,保存 “REDIS” 5 个字符,方便程序快速分辨为 RDB 文件

RDB 为二进制数据,“REDIS” 保存的不是 c 字符串

  • db_version:4 字节,为字符串表示的常数, REB 版本号

  • database

    • 零个或多个数据库,以及数据库中的键值对数据

    • 如果数据库状态为空,此处也为空,长度 0 字节

    • 数据库状态非空,根据情况不同,长度不同

  • EOF:常量,1 字节,标志 RDB 文件正文内容结束,即所有数据库所有键值对载入完成

  • check_num:8 字节无符号整数,校验和,通过前四个部分计算而来,载入时计算是否与之相同验证文件是否损坏

10.3.1 database 部分

database 可以保存任意多个非空数据库

假设 0 号、3 号数据库非空, RDB 文件如图,database 代表 0 号数据库中的所有键值对

技术图片

database 0 又可以再细分

技术图片

  • SELECTDB:1 字节,表明接下来读入的是数据库号码

  • db_number:数据库号码,可以为1 3 5 字节

  • key_value_pairs:数据库中的所有键值对数据,如果有过期时间也会保存在一起

10.3.2 key_value_pairs 部分

不带过期时间的键值对

TYPE KEY VALUE
  • TYPE:1 字节

技术图片

  • value:字符串对象,同上襦的 String 类型

带过期时间的键值对

EXPIRETIME_MS MS TYPE KEY VALUE
  • EXPIRETIME_MS:1 字节,告知程序即将读入的是毫秒为单位的过期时间
  • ms:8 字节的带符号整数,毫秒为单位为 UNIX 时间戳

10.3.3 value 编码

1.字符串对象:REDIS_RDB_TYPE_STRING

value 保存的为字符串对象,编码有 REDIS_ENCODING_INT 或者 REDIS_ENCODING_RAW

  • REDIS_ENCODING_INT

    • 长度不超过 32 位的整数

    • ENCODING 可以是 REDIS_RDB_ENC_INT8、REDIS_RDB_ENC_INT16、REDIS_RDB_ENC_INT32 代表使用几位来保存整数值 integer

    技术图片

  • REDIS_ENCODING_RAW

    • 字符串对象

    • 压缩与不压缩保存

      • 小于等于 20 字节,原样保存

      • 大于 20 字节,压缩之后再保存

      • 在服务器打开 RDB 文件压缩功能进行的

      • 否则总是无压缩保存

    • 无压缩

    技术图片

    • 压缩

      技术图片

      • REDIS_RDB_ENC_LZF:常量,表示字符串被 LZF 算法压缩了,程序会对后面三个字段使用解压缩
      • compressed_len:压缩之后的长度
      • origin_len:压缩之前的长度
      • compressed_string:压缩之后的字符串

2.列表对象:REDIS_RDB_TYPE_LIST

value 保存的是 REDIS_ENCODING_LINKEDLIST 编码的列表对象

技术图片

  • list_length:列表长度,列表保存了多少个项

  • item:列表的列表项,每个列表项都是字符串对象

    • 包含长度与实际值

    技术图片

3.集合对象:REDIS_RDB_TYPE_SET

REDIS_ENCODING_HT

技术图片

  • set_size:集合大小

  • elem:字符串对象

    • 包含长度与实际值

    技术图片

4.哈希表对象:REDIS_RDB_TYPE_HASH

REDIS_ENCODING_HT

技术图片

键与值相邻排列

5.有序集合对象:REDIS_RDB_TYPE_ZSET

REDIS_ENCODING_SKIPLIST

技术图片

成员与分值紧挨,分值为 double 浮点数,在 double、字符串中互相转换

6.INTSET 编码集合:REDIS_RDB_TYPE_INTSET

整数集合与字符串互相转换

7.ZIPLIST 编码的列表、哈希表或者有序集合

REDIS_RDB_TYPE_LIST_ZIPLIST

REDIS_RDB_TYPE_HASH_ZIPLIST

REDIS_RDB_TYPE_ZSET_ZIPLIST

压缩列表

  1. 压缩列表转换字符串

  2. 字符串保存到 RDB

  3. 字符串转换压缩列表

  4. 根据 TYPE 设置类型

    • REDIS_RDB_TYPE_LIST_ZIPLIST:列表
    • REDIS_RDB_TYPE_HASH_ZIPLIST:哈希表
    • REDIS_RDB_TYPE_ZSET_ZIPLIST:有序集合

Redis设计与实现 第 10 章 RDB 持久化

标签:czc   功能   属性   包含   否则   流程   对象   src   不同的   

原文地址:https://www.cnblogs.com/zephxu/p/14920012.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!