Redis持久化 - RDB(Redis Database)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 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属性:

    structredisService{
    //记录了保存条件的数组structsaveparam*saveparams;
    };

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

    structsaveparam{
    // 秒数time_tseconds;
    // 修改数intchanges;
    };

    上面举例的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命令的时间
    structredisServer{
    //修改计数器longlongdirty;
    // 上一次执行保存时间time_tlastlave;
    };

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

    image.png

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

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


    2.3.2 检查是否满足保存条件

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

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

    defserverCron():
    # 遍历所有保存条件forsaveparaminserver.saveparams:
    # 计算距离上次执行保存操作有多少秒save_interval=time.time() -saver.lastsave# 如果数据图的修改次数超过条件所设置的次数# 并且距离上次保存的时间超过条件所设置的时间#那么执行保存操作if (
    server.dirty>=serparam.changesandsave_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数据库实现在线游戏中的游戏玩家积分排行榜功能。
    云数据库 Redis 版使用教程
    云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
    相关文章
    |
    17天前
    |
    NoSQL Redis 数据库
    一文讲透彻Redis 持久化
    一文讲透彻Redis 持久化
    26 0
    |
    2天前
    |
    存储 NoSQL 算法
    Redis持久化&Redis主从
    Redis持久化&Redis主从
    10 0
    |
    3天前
    |
    缓存 NoSQL 关系型数据库
    深入浅出Redis(四):Redis基于RDB、AOF的持久化
    深入浅出Redis(四):Redis基于RDB、AOF的持久化
    |
    4天前
    |
    NoSQL 算法 关系型数据库
    Redis持久化 RDB & AOF
    Redis持久化 RDB & AOF
    13 0
    |
    12天前
    |
    NoSQL Redis 数据库
    |
    17天前
    |
    存储 运维 NoSQL
    |
    5月前
    |
    NoSQL Redis 数据库
    【Redis】RDB和AOF
    【Redis】RDB和AOF
    |
    7月前
    |
    NoSQL 安全 关系型数据库
    【Redis源码】详细的RDB和AOF持久化过程(五)
    【Redis源码】详细的RDB和AOF持久化过程(五)
    42 0
    |
    8月前
    |
    NoSQL Redis 数据安全/隐私保护
    redis的 rdb 和 aof 持久化方式的区别及使用场景
    redis的 rdb 和 aof 持久化方式的区别及使用场景
    148 0
    |
    4月前
    |
    NoSQL 关系型数据库 MySQL
    Redis持久化机制 RDB 和 AOF 的选择
    Redis持久化机制 RDB 和 AOF 的选择
    60 0