目录前言1. RDB 持久化1.1 RDB 文件的创建与载入1.2 自动间隔性保存1.2.1 设置保存条件1.2.2 dirty 计数器和 lastsave 属性1.2.3 检查保存条件是否满足1.3 RDB 文件1.3.1 RDB 的文
参考资料:《Redis设计与实现 第二版》;
第二部分为单机数据库的实现,主要由以下模块组成:数据库、持久化、事件、客户端与服务器;
本篇将介绍 Redis 中的持久化技术,主要有两种:RDB持久化和AOF持久化;
rdb.c/rdbSave
函数完成;rdb.c/rdbLoad
函数完成;服务器会根据 save
选项所设置的保存值,设置服务器状态 redisServer
结构的 saveparams
属性;
redisServer
的结构定义:
struct redisServer{
//...
//记录了保存条件的数组
struct saveparam *saveparams;
//
}
saveparams
属性是一个数组,每个 saveparam
结构保存了一个 save
设置的保存条件;
saveparam
的结构定义:
struct saveparam{
//秒数
time_t seconds;
//修改值
int changes;
}
dirty
属性和 lastsave
属性在 redisServer
结构体里:
struct redisServer{
//...
//修改计数器
long long dirty;
//上一次执行保存的时间
time_t lastsave;
};
dirty
计数器记录距离上一次成功执行 SAVE 命令或者 BGNAME 命令之后,服务器对数据库状态进行了多少次修改;lastsave
属性是一个 UNIX 时间戳,记录了服务器上一次成功执行 SAVE 命令或 BGSAVE 命令的时间;serverCron
默认每隔 100ms 会执行一次,其中包括检查 save 选项所设置的保存条件是否满足(遍历并检查 saveparams
数组中的所有保存条件),满足则执行 BGSAVE 命令;RDB 文件结构的逻辑图:
各个字段含义:
字段 | 长度 | 储存值 | 说明 |
---|---|---|---|
REDIS | 5字节 | “REDIS” | 在载入文件时,快速检查所载入的文件是否为 RDB 文件 |
db_version | 4字节 | 字符串表示的整数 | RDB 文件的版本号 |
databases | 0个或任意多个数据库,以及数据库中的键值对数据 | ||
EOP | 1字节 | EOP 常量 | 表示 RDB 文件正文内容的结束 |
check_sum | 8字节 | 无符号整数 | 前4个部分的校验和 |
databases
部分的逻辑结构:各字段含义:
字段 | 长度 | 存储值 | 说明 |
---|---|---|---|
SELECTDB | 1字节 | 常量 | 表示接下来读入数据库号码 |
db_number | 1、2或5字节 | 数字 | 表示数据库号码 |
key_value_pairs | 长度不定 | 数据库所有的键值对数据 |
key_value_pairs
部分的逻辑结构:各字段含义:
字段 | 长度 | 存储值 | 说明 |
---|---|---|---|
EXPIRETIME_MS | 1字节 | 数值 | 表示过期时间 |
ms | 8字节 | 数值 | 以毫秒为单位的 UNIX 时间戳 |
TYPE | 1字节 | 常量 | 代表一种对象类型或底层编码 |
key | 长度不定 | 字符串对象 | 表示键对象 |
value | 长度不定 | 各种对象 | 表示值对象 |
INTSET 编码集合的格式:
ZIPLIST编码的列表、哈希表或有序集合的格式:
不包含任何键值对的 RDB 文件:
REDIS标识 | db_version | EOF标识 | check_num |
---|---|---|---|
REDIS | 0006 | 377 | 334 263 c 360 z 334 362 v |
包含字符串键的 RDB 文件:
REDIS标识 | db_version | SELECTDB | db_number,0 号数据库 | TYPE, 表示字符串 | key | value | EOF标识 | check_num |
---|---|---|---|---|---|---|---|---|
REDIS | 0006 | 376 | 003 MSG | 005 HELLO | 377 | 207 z = 304 f T L 343 |
包含带有过期时间的字符串键的 RDB 文件:
REDIS标识 | db_version | SELECTDB 切换数据库 | EXPIRETIME_MS | ms | TYPE, 表示字符串 | key | value | EOF标识 | check_num |
---|---|---|---|---|---|---|---|---|---|
REDIS | 0006 | 376 | 374 | 2 365 336 @ 001 | 003 MSG | 005 HELLO | 377 | 212 231 x 247 252 } 021 306 |
包含一个集合键的 RDB 文件:
REDIS标识 | db_version | SELECTDB 切换数据库 | 常量 REDIS_RDB_TYPE_SET | key | 集合大小 | 第一个元素 | 第二个元素 | 第三个元素 | EOF常量 | check_num |
---|---|---|---|---|---|---|---|---|---|---|
REDIS | 0006 | 376 | 002 | 004 LANG | 003 | 004 RUBY | 004 JAVA | 001 C | 377 | 202 312 r 352 346 305 * 023 |
AOF 持久化功能可分为:追加(append)、文件写入、文件同步(sync)三个步骤;
AOF 文件中的所有命令都以 Redis 命令请求协议的格式保存;
当 AOF 持久化功能打开时,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器状态的 aof_buf
缓冲区的末尾:
struct redisServer{
//...
//AOF 缓冲区
sds aof_buf;
};
AOF 文件的写入与同步依赖事件循环 loop,每次循环主要有三个工作:
aof_buf
中的内容追加到 AOF 文件中;flushAppendOnlyFile() 函数的行为由服务器配置的 appendfsync
选项的值决定,该值有三种不同的行为:
appendfsync 选项的值 | flushAppendOnlyFile 函数的行为 | 效率与安全性 |
---|---|---|
always | 将 aof_buf 缓冲区中的所有内容写入并同步到 AOF 文件 | 效率最慢,安全性最高 |
everysec | 将 aof_buf 缓冲区中的所有内容写入并同步到 AOF 文件,如果上次同步 AOF 文件的事件距离现在超过 1s ,则对再次 AOF 文件进行同步,并且这个同步由一个线程专门负责 | 效率高 |
no | 将 aof_buf 缓冲区中的所有内容写入到 AOF 文件,但不对 AOF 文件进行同步,何时同步由操作系统决定 | 效率最高,安全性最低 |
redis.h/REDIS_AOF_REWRITE_ITEMS_PER_CMD
确定;Redis 服务器设置一个 AOF 重写缓冲区,以保证:
子进程完成 AOF 重写工作后,向父进程发送一个信号,父进程接到信号后调用信号处理函数,执行以下工作:
只有号处理函数执行时会对服务器进程(父进程)造成阻塞;
--结束END--
本文标题: Redis | 第5章 Redis 中的持久化技术《Redis设计与实现》
本文链接: https://www.lsjlt.com/news/8942.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
2024-05-03
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0