• 第10章 RDB持久化


      Redis是一种内存数据库,掉电即失,为了解决这个问题Redis提供了RDB持久化功能,该功能可以把Redis中的内容以RDB文件的形式存储在硬盘上,并且每次RedisServer启动的时候都会尝试从RDB文件中恢复内容。

    10.1 RDB文件的创建与载入

      创建RDB文件可以使用SAVA BGSAVE,前者是主进程直接创建RDB并保存内容,后者是新建子进程去持久化Redis内容,所以前者是阻塞后者是非阻塞的。

      RDB文件的载入是自动的,只要Redis服务器启动的时候能够发现RDB文件的存在就会载入RDB文件。

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

      SAVA命令会阻塞Redis服务器,直到SAVA命令执行完毕才会处理客服端的新的请求。

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

      BGSAVA执行的时候不会阻塞Redis服务器,但是SAVA BGSAVA BGREWRITEAOF会有所不同

    • 禁止SAVA命令执行,避免Redis进程,和用于执行BGSAVA的子进程同时执行rdbSAVE产生竞态条件
    • 机制BGSAVA,同样是为了避免静态条件
    • BGREWRITEAOF会被延迟到BGSAVA执行完毕,这是出于磁盘性能考虑,两个命令同时执行会执行大量的磁盘读写操作

    10.2 自动间隔保存

      因为BGSAVA不会阻塞Redis服务器,所以Redis会按照一定的时间间隔自动的保存Redis内容并生成RDB文件。

      保存时间间隔可以在config文件中设置,如果没有设置将会使用默认的保存间隔。save 900 1代表如果900秒内执行了一次修改,就会执行BGSAVA命令。

      config文件中的关于BGSAVE间隔的设置最终会体现在redisServer中,可以看到关于保存时间的设置是针对整个服务器的,而非数据库的。其中savaparams数组记录着所有的保存条件,每一个savaparams记录着秒数和修改数。

     

      除了保存数和秒数外,redisServer结构还会记录上一次保存的时间,和上一次保存后服务器修改了多少次,从而判断当前Redis的状态是否满足savaparams的保存条件。从savaparams和dirty lastsave的存储位置可以看到,Redis使用RDB持久化是针对整个Redis服务器的,而非某个具体的数据库。因为对16个数据库无论哪个修改都会使dirty增加。

      有了保存条件和记录当前Redis状态的字段后,Redis会执行一个周期性的函数,默认间隔是100毫秒,去轮询查询当前的条件是否满足保存的条件。

     10.3 RDB文件结构

      一个RDB文件主要由两部分组成,一部分是常量:REDIS魔数、EOF文件结束标志、db_version代表当前数据库的版本,也可以认为是一个常数。另一部分是database,真正用来存储数据库中的键值对和过期时间。

    10.3.1 databases部分

      

      一个完整的结构如上所示,databases部分由SELECTDB开始,紧接着是数据库的编号,最后pairs里面存储着真正的键值对。

    10.3.2 key_value_pairs

      根据键值对是否带有过期时间key_value_pairs的结构有所不同。

    • TYPE,记录着value的类型,根据TYPE的不同Redis会用不同的方法去解释读进来的value字段
    • key,键值对中的key,一定是String类型的
    • value,键值对中的value,其类型由TYPE字段决定

    10.3.3 value的编码

    10.3.3.1 字符串对象

      字符串对象对应的TYPE是REDIS_RDB_TYPE_STRING,即使是字符串也有两种编码REDIS_ENCODING_INT 和 REDIS_ENCODING_RAW。

      如果字符串的编码是REDIS_ENCODING_INT说明此时字符串内存储的是一个整数。

      如果字符型的编码是REDIS_ENCODING_RAW,说明字符串此时存储的是一个字符串,而又根据字符串的长度不同分为压缩表示和非压缩表示。

      当字符串的长度小于20个字节的时候会采用下面的方式存储。

      

      当Redis开启了字符串压缩表示且字符串的长度大于20个字节,字符串会被使用LZF算法压缩并存储。

      

    10.3.3.2 列表对象

      列表对象对应的TYPE是REDIS_RDB_TYPE_LIST,结构如下。其中list_lenght代表列表的长度,itemx代表列表中的每一项。Redis会用解析字符串的方式处理List中的每一个元素。

       如一个存储了三个元素的链表如下所示,可见整数和字符串在Redis中都是使用String类型来存储的。

       

    10.3.3.3 集合对象

      集合对象对应的KEY是REDIS_RDB_TYPE_SET,结构和list看起来差不多。集合中每一个元素也都是String类型。

      

    10.3.3.4 哈希表集合

      哈希表对应的TYPE是REDIS_RDB_TYPE_HASH,也没啥特殊的,开头用来记录长度,后续用String类型来记录key-value。

    10.3.3.5 有序集合

      REDIS_RDB_TYPE_ZSET。

      

  • 相关阅读:
    用PYTHON修改电脑IP地址
    PYTHON os 模块详解
    django 笔记
    PYTHON实战目录
    群晖PLEX设置方法
    jellin docker 群晖设置方法转自先生
    PYTHON ftp 上传方法
    打包驱动EXSI
    我的PYTHON老师ALEX
    安装WHELL
  • 原文地址:https://www.cnblogs.com/AshOfTime/p/10675072.html
Copyright © 2020-2023  润新知