开发者社区> 游客swjfd4h6nplio> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Redis持久化 - RDB(Redis Database)

简介: Redis持久化
+关注继续查看

         Redis是内存数据库,它将自己的数据存储在内存中,如果不想办法把数据保存到磁盘里面,一旦服务器进程退出,那么服务器的数据就会消失不见。为了解决这个问题,Redis提供了RDB持久化功能,这个功能可以将Redis在内存中的数据保存到磁盘中,防止数据丢失。

        Redis持久化既可以手动执行,也可以根据服务器配置定期执行,该功能可以将某个时间点的数据保存到一个RDB文件中。

image.gifimage.png

        Redis持久化功能所生成的RDB文件是一个经过压缩的二进制文件,可以通过该文件还原生成RDB文件时的数据。因为RDB文件存放在磁盘中,所以即使宕机,我们也可以通过RDB文件恢复Redis数据。

image.gifimage.png

1、RDB文件的创建和载入

1)创建

        有两个Redis命令可以生成RDB文件,一个是SAVE,一个是BGSAVE

    • SAVE命令会阻塞服务进程,期间服务器不能处理任何命令请求。只有执行完SAVE命令之后,客户端发送的命令才会被执行。image.gif

    image.png

    func SAVE(){
        // 创建rdb文件
        rdbSAVE()
    }

    image.gif

    • BGSAVE命令不会阻塞服务进程,会派生出一个子进程,然后由子进程创建RDB文件,服务器进程继续处理命令请求

     image.png       

    def BGSAVE () :
        # 创建子进程
        pid = forkl
        if pid == 0:
            # 子进程货责创建RDB 文件
            rdbsave()
            # 完成之后向父进程发送信号
            signal_parent ()
        elif pid > 0:
            # 父进程經续处理命令请求,并通过轮询等待子进程的信号
            kandle_request_and_wait_signal()
        else:
            #处理出错情况
            handle_fork_error()

    image.gif


    2)载入

    RDB文件的载入是在服务器启动时自动执行的,只要Redis服务器在启动时检测到RDB文件的存在,它就会自动载入RDB文件。服务器在载入RDB另外AOF文件的更新频率比RDB更新频率高,所以:

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

    image.png

    载入RDB文件的实际工作由rdb.c/rdbLoad函数完成

    image.png


    2、BGSAVE自动间隔保存的底层实现

    2.1 save选项配置

    BGSAVE命令可以在不阻塞服务进程的情况下执行,所以Redis允许用户通过设置服务器的save选项,让服务器每隔一段时间自动执行一次BGSAVE命令。例如,如果我们向服务器提供以下配置:

            时间间隔 次数
    save    900     1
    save    300     10
    save    60      10000

    那么只要满足以下三个条件中的任意一个,BGSAVE命令就会被执行:

    • 服务器在900秒内,对数据库进行了至少1次的修改。
    • 服务器在300秒内,对数据库进行了至少10次的修改。
    • 服务器在600秒内,对数据库进行了至少10000次的修改。


    2.2 保存save配置的底层结构

    服务器程序会根据save选项,设置服务器状态redisService结构的saveparams属性:

    struct redisService{
        //记录了保存条件的数组
        struct saveparam *saveparams;
    };

    saveparams属性是一个数据,数组中的每个元素都是一个saveparam结构,每个saveparam结构都保存了一个save选项设置的保存条件:

    struct saveparam{
        
        // 秒数
        time_t seconds;
        
        // 修改数
        int changes;
    };

    上面举例的save选项的saveparams结构如下:

    image.png


    2.3 BGSAVE自动间隔性保存的实现流程

    BGSAVE实现需要两个步骤:

        1. dirty计数器和lastsave记录已修改的次数和上次执行save/bgsave的时间戳
        2. 检查是否满足保存条件


    2.3.1 dirty计数器和lastsave属性

    服务器除了saveparams数组之外,还维持着一个dirty计数器和一个lastsave属性:

        • dirty计数器记录距离上一次成功执行SAVE/BGSAVE命令之后,服务器读数据库进行了多少次修改(包括写入、删除、更新等操作)。
        • lastsave属性是一个UNIX时间戳,记录了服务器上一次成功执行SAVE/BGSAVE命令的时间
    struct redisServer{
        //修改计数器
        long long dirty;
        
        // 上一次执行保存时间
        time_t lastlave;
    };

    当服务器成功执行了一个数据库修改命令之后,程序就会对dirty计数器进行更新:命令修改了多少次数据库,dirty计数器的值就会增加多少。

    image.png

    上图展示了服务器包含的dirty计数器和lastsave属性,说明如下:

        • dirty计数器的值为123,表示服务器在上次保存之后,对数据库状态进行了123次修改。
        • lastsave属性则记录了服务器上次执行保存操作的时间为1378270800.


    2.3.2 检查是否满足保存条件

    Redis的服务器周期操作函数serverCron默认每隔100毫秒就会执行一次,它的其中一项工作就是检查save选项中设置的保持条件是否满足,如果满足就执行BGSAVE命令。

    serverCron函数检查保存条件的过程伪代码:

    def serverCron():
        
        # 遍历所有保存条件
        for saveparam in server.saveparams:
            
            # 计算距离上次执行保存操作有多少秒
            save_interval = time.time() - saver.lastsave
            
            # 如果数据图的修改次数超过条件所设置的次数
            # 并且距离上次保存的时间超过条件所设置的时间
            #那么执行保存操作
            if (
                server.dirty >= serparam.changes 
                and save_interval > saveparam.seconds
            ):
                BGSAVE()

    程序会遍历检查saveparams数组中的所有保存条件,只要有任意一个条件被满足,那么服务器就会执行BGSAVE命令


    3 RDB文件结构

    RDB文件名为:dump.rdb;下图展示了一个完整的RDB文件包含的各个部分:

    image.png

        • REDIS:5字节,程序在载入文件时,可以通过这5个字节判断是否是RDB文件。
        • db_version:4字节,记录RDB文件的版本号。
        • databases:redis的数据库,包含各个数据库中的键值对数据。
        • EOF:1字节,标志RDB正文的结束。
        • check_sum:用于检查RDB文件是否损坏或者出错。


    3.1 databases结构

    下图展示了databases结构:

    image.png

        • SELECTDB:1字节,当程序遇到这个值,它将会知道接下来要读的是一个数据库号码。
        • db_number:数据库号码,服务器会调用SELECT,根据读入的数据库号码进行数据库切换。
        • key_value_pairs:保存了数据库中的所有键值对数据。


    下图展示了一个完整的RDB文件结构:

    image.png


    3.2 key_value_pairs结构

    RDB文件中的每个key_value_pairs部分都保存了一个或以上数量的键值对,如果键值对带有过期时间的话,那么键值对的过期时间也会被保存在内。

        • 不带过期时间的键值对:

    image.png

        • 带过期时间的键值对

    image.png

    其中TYPE表示该键值对的类型

    版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

    相关文章
    Redis 高可用之持久化(下)
    一、Redis 高可用 1.1 什么是高可用 在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。 但是在Redis语境中,高可用的含义似乎要宽泛一些,除了保证提供正常服务( 如主从分离、快速容灾技术),还需要考虑数据容量的扩展、数据安全不会丢失等。
    0 0
    Redis 高可用之持久化(上)
    一、Redis 高可用 1.1 什么是高可用 在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。 但是在Redis语境中,高可用的含义似乎要宽泛一些,除了保证提供正常服务( 如主从分离、快速容灾技术),还需要考虑数据容量的扩展、数据安全不会丢失等。
    0 0
    【Redis】Redis AOF持久化
    写入AOF文件不就是同步了吗?这里的写入和 同步的区别是什么? 这里的写入AOF文件, 在现代操作系统中,用户调用了write()函数来将数据写入到文件中,但是操作系统通常会将写入的数据暂时保存在一个 ** 内存缓冲区** 里面,等这个缓冲区的空间被填满、或者超过了指定的时限之后
    0 0
    linux安装redis(保姆级-安装包方式安装-版本6.2.7-解决aof持久化问题)
    linux安装redis(保姆级-安装包方式安装-版本6.2.7-解决aof持久化问题)
    0 0
    Redis持久化(少年一贯快马扬帆,道阻且长不转弯)(二)
    Redis持久化(少年一贯快马扬帆,道阻且长不转弯)(二)
    0 0
    Redis持久化(少年一贯快马扬帆,道阻且长不转弯)(一)
    Redis持久化(少年一贯快马扬帆,道阻且长不转弯)(一)
    0 0
    文章
    问答
    文章排行榜
    最热
    最新
    相关电子书
    更多
    Redis Cluster的基本原理
    立即下载
    高并发分布式缓存Redis6.0
    立即下载
    Codis 集群演化与 Redis 异步迁移
    立即下载