美文网首页Redis相关
Redis第10章 RDB持久化

Redis第10章 RDB持久化

作者: Oliver_Li | 来源:发表于2020-02-09 17:40 被阅读0次
  • 前言:Redis是内存数据库,程序进程意外崩溃时,内存中的数据就会丢失,所以Redis提供了RDB和AOF两种把数据持久化到硬盘的方式,Redis启动时会读取保存的文件恢复数据。
  • 简单说RDB会定期生成一个全量数据的压缩二进制文件保存,而AOF则是一个文件不停写入Redis执行语句,各有优缺点,后面会具体分析。
  • Redis4.0以后提供了一种混合持久化aof-use-rdb-preamble,将RDB数据写到AOF文件中,原先AOF依然写入,既保证速度又保证数据安全。

10.1 RDB文件的创建与载入

  • bgsave和save两个命令可以实现手动触发RDB持久化,通过rdb.c/rdbSave函数完成:
    • save会阻塞Redis服务器进程
    • bgsave会创建子进程,不会阻塞Redis服务器
  • Redis启动时会检测RDB文件自动载入:
    • AOF更新频率比RDB高,如果开启AOF功能会优先使用AOF文件恢复数据,否则才会使用RDB文件
10.1.1 SAVE命令执行时的服务器状态
  • save命令会阻塞Redis服务器,只有在执行完save命令后重新开始接收请求,才会继续处理命令
10.1.2 BGSAVE命令执行时的服务器状态
  • BGSAVE执行期间,客户端发送SAVE命令会被拒绝,避免竞争
  • BGSAVE执行期间,BGSAVE命令也会拒绝
  • BGSAVE执行期间,BGREWRITEAOF命令会被推后,BGREWRITEAOF执行时BGSAVE也会推后,不拒绝但不能同时执行。BGREWRITEAOF是AOF版的异步持久化命令,逻辑上不会有冲突,但为了避免大量磁盘写入所以不能同时执行。
10.1.3 RDB文件载入时的服务器状态
  • 阻塞

10.2 自动间隔保存

  • 通过配置文件的save选项可以自动触发BGSAVE命令,例如:
save 900 1
save 300 10
save 60 10000
  • 满足以上三个中的任意一个条件,就会执行BGSAVE:
    • 900秒内至少修改过1次
    • 300秒内至少修改过10次
    • 60秒内至少修改过10000次
10.2.1 设置保存条件(自动保存的内部实现)
  • redisServer结构的saveparam属性:
struct redisServer{
//...
//记录了保存条件的数组
struct saveparam *saveparam
//...
}
struct saveparam{
//秒数
time_t seconds;
//修改数
int changes;
}
10.6.png
10.2.2 dirty计数器和lastsave属性
  • dirty记录上次执行BGSAVE和SAVE之后,数据库进行了多少次修改,每次修改数据dirty会递增。
  • lastsave记录上次执行BGSAVE和SAVE的时间
struct redisServer{
//...
// 修改计数器
long long dirty;
// 上一次执行保存的时间
time_t lastsave;
//...
}
10.2.3 检查保存条件是否满足
  • 之前提到过周期函数serverCron,默认每隔100毫秒执行一次,其中就有关于save的任务:
    • 通过lastsave计算当前时间和上次自动执行BGSAVE时间间隔
    • 通过lastsave和dirty遍历配置条件,如果满足就执行BGSAVE

10.3 RDB文件结构

  • RDB存储总体结构如下:


    RDB文件结构.png
  • 第一层(整体):
    • REDIS:一个二进制常量,用于识别RDB文件,没有其他特殊意义
    • db_version:rdb文件的版本,书中版本是6,意思是第六版的RDB文件结构
    • database:存储具体数据的位置,下个小结展开
    • EOF:结束标志
    • check_sun:8字节无符号整数,前面的部分求和,检验文件是否出错
  • 第二层(以db0和3有数据为例):
    • 如果Redis所有库都没有数据,这部分就为空
  • 第三层(单个db):
    • SELECTDB:1字节常量,表示后面是数据库编号
    • db_number:具体数据库编号,读取RDB到这时Redis会切换到相应编号的库
    • key_value_pairs:库里具体的key value
  • 第四层(key_value_pairs内部):
    • EXPIRETIME_MS:常量,表示后面的是这个键值对的过期时间,如果没设置过期,EXPIRETIME_MS和ms都是空
    • ms:Unix时间戳,代表超时时间
    • TYPE:常量,代表value的存储类型一共9种,下个小节说明
    • key:字符串,具体对象的key
    • value:value根据TYPE不同存储的结构也不同,下面具体分析每种value存储的形式
10.3.3 value的编码(关联第八章):
  1. 字符串对象(TYPE常量是REDIS_RDB_TYPE_STRING):
  • 和对象底层实现一样,RDB存储时底层编码encoding也会不同,都体现在value内部。第八章提到字符串有三种编码REDIS_ENCODING_INT、REDIS_ENCODING_RAW、REDIS_ENCODING_EMBSTR,我在看书时没发现embstr的说明,两种本质都是SDS,所以猜测都算作raw了,当然这个不影响后续概念理解,总体分为 int 和 raw 两种。
  • 数字(REDIS_ENCODING_INT):value结构为encoding + integer ,这种类型不会超过32位,integer为具体数据,encoding根据数据长度分为 REDIS_RDB_ENC_INT8REDIS_RDB_ENC_INT16REDIS_RDB_ENC_INT32
  • 字符串(REDIS_ENCODING_RAW):浮点或整形数字过长或者字符串会用REDIS_ENCODING_RAW,当字符串大于20字节时存储RDB数据会压缩(redis.config的rdbcompression默认开启)。
    • 无压缩:结构是len + string长度 + 数据原样保存,这种结构里就省略了encoding部分
    • 压缩时:结构是REDIS_RDB_ENC_LZF + compressed_len + origin_len + compressed_string,encoding默认REDIS_RDB_ENC_LZFcompressed_len压缩后长度,origin_len原数据长度,compressed_string压缩后的数据
  1. 列表对象(REDIS_RDB_TYPE_LIST):
  • 列表有两种编码linkedlist和ziplist,这里默认linkedlist,ziplist后面单独说明,元素都是字符串,只会有REDIS_ENCODING_LINKEDLIST一种,结构为list_lenth + item1_len + item1_str + item2_len + item2_str ...list_lenth表示元素个数,len代表字符串长度,*_str是具体数据
  1. 集合对象(REDIS_RDB_TYPE_SET):
  • 默认编码为ht,set_size + elem1_len + elem1_str + elem2_len + elem2_str ...,名字换一下,结构和属性代表的意思一样。
  1. 哈希表对象(REDIS_RDB_TYPE_HASH
  • 默认编码为ht,hash_size + key1_size + key1_str + value1_size + value1_str + key2_size...,其中hash_size是键值对个数,后续key + value循环到结尾也很好理解。
  1. 有序集合对象(REDIS_RDB_TYPE_ZSET
  • 默认编码spiplist,有序集合和上面结构的区别只是需要记录一个分值sorted_set_size + member1 + score1 + member2 + score2...,其中每个member和score前面也都有一个计数这里就不啰嗦了
  1. INTSET编码的集合(REDIS_RDB_TYPE_SET_INTSET
  • 集合对象的第二种编码实现,和REDIS_RDB_TYPE_SET相同,只是读入时把字符串对象,转成了整数集合对象。
  1. ZIPLIST编码的集合(REDIS_RDB_TYPE_LIST_ZIPLIST、REDIS_RDB_TYPE_ZSET_ZIPLIST、REDIS_RDB_TYPE_HASH_ZIPLIST
  • 有三种基本对象底层用到了ZIPLIST,列表、哈希表和有序集合。读取时会根据TYPE不同生成相应的基本类型。

相关文章

  • Redis缓存持久化策略

    Redis RDB持久化原理 简介:rdb持久化方案配置讲解,redis的开发者是怎么实现rdb的 rdb持久化配...

  • Redis持久化

    Redis持久化方式有两种:RDB和AOF。 1 RDB持久化 RDB(Redis Database)持久化是把当...

  • redis-2

    redis-2 redis的持久化 Redis 提供了 RDB 和 AOF 两种持久化方式。 RDB RDB 是把...

  • 03-redis持久化

    Redis持久化 两种方式持久化: RDB持久化 - 全量 AOF持久化 - 增量 RDB持久化 RDB文件的生成...

  • Redis的持久化方式:RDB和AOF

    一,redis的持久化方式:RDB和AOF RDB,即Redis Database RDB持久化方式:在指定的时间...

  • 「高频面试题」Redis的持久化方式有哪些?

    RDB RDB(Redis DataBase)持久化是把当前Redis中全部数据生成快照保存在硬盘上。RDB持久化...

  • redis mongodb持久化的方式

    redis持久化方式(两种) RDB持久化 redis提供了RDB持久化的功能,这个功能可以将redis在内存中的...

  • 2020-02-21 记录redis(8)

    redis持久化,两种持久化方式: RDB方式 AOF方式 持久化的使用方式: RDB 优势: 1、redis的数...

  • Redis-分布式缓存(一)

    零、本文纲要 一、单机Redis的问题二、Redis持久化(一)RDB持久化(二)AOF持久化(三)RDB与AOF...

  • Redis 持久化

    Redis 持久化 RDB RDB 持久化方式类似于快照,执行 SAVE BGSAVE命令时可以触发 RDB 持久...

网友评论

    本文标题:Redis第10章 RDB持久化

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