美文网首页
Redis-持久化

Redis-持久化

作者: 稻壳_be03 | 来源:发表于2019-08-02 13:52 被阅读0次

    Redis-持久化

    一、RDB持久化

            为了解决服务器进程退出导致数据丢失,Redis提过了RDB持久化功能,可以将Redis在内存中的数据保存到磁盘中,避免数据意外丢失。

            RDB持久化既可以手动执行,也可以根据服务器配置选项定期执行,该功能将某个时间点上的数据库状态保存到一个RDB文件中。生成的RDB文件是一个经过压缩的二进制文件,通过该文件,可以还原生成RDB文件时的数据库状态。

    1、RDB文件的创建与载入

    命令:SAVE、BGSAVE

            SAVE 命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求。

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

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

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

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

    1)如果服务器开启了AOF持久化公共能,那么服务器会优先使用AOF文件来还原数据库状态

    2)只有在AOF持久化功能关闭状态时,服务器才会使用RDB文件来还原数据库状态

    当SAVE命令执行时,Redis服务器会被阻塞,客户端发送的所有命令请求都会被拒绝

    当BGSAVE命令执行时,Redis服务器任然可以继续处理客户端命令请求,但是,在BGSAVE命令执行期间,服务器处理SAVE、BGSAVE、BGREWRITEAOF三个命令的方式会和平时有所不同。

            1)在BGSAVE命令执行期间,客户端发送的SAVE命令会被服务器拒绝

            2)在BGSAVE命令执行期间,客户端发送的BGSAVE命令会被服务器拒绝

            3)BGREWRITEAOF和BGSAVE命令不能同时执行:如果BGSAVE 命令正在执行,BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕之后执行;如果BGREWRITEAOF命令正在执行,BGSAVE命令会被服务器拒绝

    服务器载入RDB期间,会一直处于阻塞状态。

    2、自动间隔性保存

            因为BGSAVE命令可以在不阻塞服务器进程的情况下执行,所以Redis允许用户通过设置服务器配置的save选项,让服务器每隔一段时间自动执行BGSAVE命令。

            用户可以通过save选项设置多个保存条件,只要其中一个条件被满足,服务器就会执行BGSAVE命令。

    2.1、设置保存条件

            当服务器启动时,用户可以通过指定配置文件或传入参数的方式设置save选项,如果用户没有主动设置save选项,服务器默认设置

            save  900  1             (服务器在900秒之内,对数据库进行了至少1次修改)

            save  300  10         (服务器在300秒之内,对数据库进行了至少10次修改)

            save  60  10000     (服务器在60秒之内,对数据库进行了至少10000次修改)

            服务器程序会根据save选项所设置保存条件,设置服务器状态redisServer的saveparams属性。

    2.2、dirty计算器和lastsave属性

            dirty计数器 记录距离上一次成功执行SAVE或BGSAVE命令之后,服务器对数据库状态进行了多少次修改(包括写入、删除、更新操作)

            lastsave属性 是一个UNIX时间戳,记录服务器上一次成功执行SAVE命令或者BGSAVE命令的时间

    2.3、检查保存条件是否满足

            Redis的服务器周期性操作函数serverCron默认100毫秒执行一次,该函数用于对正在运行的服务器进行维护,其中一项工作就是检查save选项所设置的保存条件是否满足,如果满足,就执行BGSAVE命令。

    3、RDB文件结构

    RDB文件最开头是REDIS部分,这个部分的长度为5字节,保存"REDIS"五个字符。通过这5个字符,判断载入的文件是否RDB文件。

    db_version长度4字节,是一个字符串表示的整数,记录RDB文件的版本号

    databases部分包含零个或任意多个数据库,以及各个数据库中的键值对数据:

            1)如果服务器的数据库状态为空,则这个部分为空,长度为0字节

            2) 如果服务器的数据库状态为非空,那么这个部分也为非空,根据键值对数量、类型和内容不同,长度也会有所不同

    EOF常量长度为1字节,标志RDB文件正文内容结束

    check_sum是一个8字节的无符号整数,保存一个校验值,是通过对REDIS、db_version、databases、EOF四个部分内容计算得到,用来检查文件是否损坏。

    databases部分

            一个RDB文件的databases部分可以保存任意多个非空数据库,每个非空数据在RDB文件中都可以保存SELECTDB、db_number、key_value_pairs三部分

    SELECTDB常亮长度1字节,标识数据库结构的开始

    db_number保存数据库号码,可以是1字节、2字节、5字节。当读入db_number部分后,会调用SELECT命令,切换到相应数据库

    key_value_pairs部分保存数据库中所有的键值对数据,如果键值对带有过期时间,则过期时间和键值对保存在一起。

    key_value_pairs部分

            不带过期时间的键值对由 TYPE、key、value三部分组成

            带有过期时间的键值对 由EXPIRETIMES_MS、ms、TYPE、key、value组成

            EXPIRETIMES_MS 常量,1个字节、标志接下来是一个带过期时间的键值对,单位毫秒

            ms        8字节带符号整数,记录一个以毫秒为单位的UNIX时间戳,表示键值对的过期时间

       value编码

            value部分保存一个值对象

    二、AOF持久化

    Redis还提供了AOF持久化功能,AOF通过保存Redis服务器所执行的写命令来记录数据库状态

    1、AOF持久化的实现

            AOF持久化实现可以分为命令追加(append)、文件写入、文件同步(sync)三个步骤

    1.1、命令追加

            当AOF持久化工能处于打开状态时,服务器在执行一个写命令后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓存区的末尾

    1.2、AOF文件的写入与同步

            Redis服务进程就是一个事件循环(loop),这个循环中的文件事件负责接收客户端的命令请求,以及向客户端发送的命令回复,

            因为服务器在处理文件事件时可能执行写命令,使得一些内容追加到aof_buf缓存区,所以在服务器结束一个事件循环之前,会调用flushAppendOnlyFile函数,考虑是否需要将aof_buf缓冲区中的内容写入和保存到AOF文件。

            flushAppendOnlyFile函数的行为有服务器配置的appendfsync选项决定

            如果用户没有主动设置appendfsync选项,默认为everysec。

    2、AOF文件的载入与数据还原

            Redis读取AOF文件并还原数据库状态的步骤:

    1)创建一个不带网络连接的客户端

    2)从AOF文件中分析并读取一条写命令

    3)使用步骤1创建的伪客户端执行步骤2读取的写命令

    4)重复执行步骤2和步骤3,直到AOF文件中所有写命令都处理完毕。

    3、AOF重写

            为了解决AOF文件体积膨胀的问题,Redis提供了AOF重写(rewirte)功能,通过该功能,可以创建一个新的AOF文件替代现有的AOF文件

    3.1 、AOF重写的实现

            因为aof_rewrite函数生成的新AOF文件只包含还原当前数据库所必须的命令,所以新AOF文件不会浪费硬盘空间

    3.2、AOF后台重写

            服务器直接调用aof_rewrite函数,则无法处理客户端发来的命令请求。

            为了解决后台重写数据不一致的问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当Redis服务器执行一个写命令之后,会同时将这个命令发送给AOF缓冲区和AOF重写缓冲区。

    相关文章

      网友评论

          本文标题:Redis-持久化

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