Redis----RDB持久化

参考博客:https://www.cnblogs.com/ysocean/p/9114268.html
这个博客总结的不错,在他的基础上稍加改动

一、什么是RDB持久化

        由于 Redis 是一个内存数据库,所谓内存数据库,就是将数据库中的内容保存在内存中,这与传统的MySQL,Oracle等关系型数据库直接将内容保存到硬盘中相比,内存数据库的读写效率比传统数据库要快的多(内存的读写效率远远大于硬盘的读写效率)。但是保存在内存中也随之带来了一个缺点,一旦断电或者宕机,那么内存数据库中的数据将会全部丢失。

        为了解决这个缺点,Redis提供了持久化功能,将内存数据持久化到硬盘,避免数据意外丢失。利用持久化文件来恢复数据库数据。Redis 支持两种形式的持久化,一种是RDB快照(snapshotting),另外一种是AOF(append-only-file)。RDB是Redis用来进行持久化的一种方式,是把当前内存中的数据集快照写入磁盘,也就是 Snapshot 快照(数据库中所有键值对数据)。恢复时是将快照文件直接读到内存里。

二、RDB持久化的触发机制

        RDB可以自动触发和手动触发

1、手动触发

两个Redis命令可以用于生成RDB文件:SAVE和BGSAVE

1、SAVE

        该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。

        显然该命令对于内存比较大的实例会造成长时间阻塞,这是致命的缺陷,为了解决此问题,Redis提供了第二种方式。

2、BGSAVE

        执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。

        基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。

2、自动触发

        自动触发通过Redis.conf 配置文件中的关键字save实现,这里是用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。比如“save m n”。表示m秒内数据集存在n次修改时,自动触发BGSAVE(这个命令下面会介绍,手动触发RDB持久化的命令)

默认如下配置:

save 900 1:表示900 秒内如果至少有 1 个 key 的值变化,则保存
save 300 10:表示300 秒内如果至少有 10个 key 的值变化,则保存
save 60 10000:表示60 秒内如果至少有 10000 个 key 的值变化,则保存

3、自动触发原理:

Redis的save m n自动触发,是通过serverCron函数、dirty计数器、和lastsave时间戳来实现的。自动触发的过程:(转自链接:https://www.jianshu.com/p/b821acded5b3)

  • serverCron是Redis服务器的周期性操作函数,默认每隔100ms执行一次;该函数对服务器的状态进行维护,其中一项工作就是检查 save m n 配置的条件是否满足,如果满足就执行bgsave,程序会遍历保存的saveparams数组中所有的SAVE条件,只要任意一个条件被满足,就执行BGSAVE。

  • dirty计数器是Redis服务器维持的一个状态,记录了上一次执行bgsave/save命令后,服务器状态进行了多少次修改(包括增删改);而当save/bgsave执行完成后,会将dirty重新置为0。例如,如果Redis执行了set mykey helloworld,则dirty值会+1;如果执行了sadd myset v1 v2 v3,则dirty值会+3;注意dirty记录的是服务器进行了多少次修改,而不是客户端执行了多少修改数据的命令。

  • lastsave时间戳也是Redis服务器维持的一个状态,记录的是上一次成功执行save/bgsave的时间。

  • save m n的原理如下:每隔100ms,执行serverCron函数;在serverCron函数中,遍历save m n配置的保存条件,只要有一个条件满足,就进行bgsave。对于每一个save m n条件,只有下面两条同时满足时才算满足 :

        当前时间     lastsave > m
        计数器        dirty >= n

Redis有个服务器状态结构:

struct redisService{
          //1、记录保存save条件的数组 
           struct saveparam *saveparams ;
          //2、修改计数器 
           long long dirty;
          //3、上一次执行保存的时间 
           time_t lastsave;
}

①、首先看记录保存save条件的数组 saveparam,里面每个元素都是一个 saveparams 结构:

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

前面我们在 redis.conf 配置文件中进行了关于save 的配置:

save 900 1:表示900 秒内如果至少有 1 个 key 的值变化,则保存
save 300 10:表示300 秒内如果至少有 10个 key 的值变化,则保存
save 60 10000:表示60 秒内如果至少有 10000 个 key 的值变化,则保存

那么服务器状态中的saveparam 数组中会保存SAVE配置:
在这里插入图片描述
②、dirty 计数器和lastsave 属性

          dirty 计数器记录距离上一次成功执行 save 命令或者 bgsave 命令之后,Redis服务器进行了多少次修改(包括写入、删除、更新等操作)。

          lastsave 属性是一个时间戳,记录上一次成功执行 save 命令或者 bgsave 命令的时间。

          通过这两个命令,当服务器成功执行一次修改操作,那么dirty 计数器就会加 1,而lastsave 属性记录上一次执行save或bgsave的时间,Redis 服务器还有一个周期性操作函数 severCron ,默认每隔 100 毫秒就会执行一次,该函数会遍历并检查 saveparams 数组中的所有保存条件,只要有一个条件被满足,那么就会执行 bgsave 命令。

          执行完成之后,dirty 计数器更新为 0 ,lastsave 也更新为执行命令的完成时间

三、使用RDB文件恢复数据

          将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可,redis就会自动加载文件数据至内存了。Redis 服务器在载入 RDB 文件期间,会一直处于阻塞状态,直到载入工作完成为止。

四、RDB文件结构

图片转自:https://www.cnblogs.com/huangxincheng/archive/2015/12/25/5074998.html
REDIS:最开头REDIS部分,长度为5个字节,保存着“Redis”五个字符,通过这五个字符,可以快速检测载入的字符是否是RDB文件

  • db-version:Redis版本号
  • datebases:数据库以及数据库的键值对,
  • EOF:标志正文结束
  • check_sum:校验和
    图片来源:https://www.cnblogs.com/huangxincheng/archive/2015/12/25/5074998.html

五、RDB的优势和劣势

①、优势

1.RDB是一个非常紧凑(compact)的文件,它保存了redis 在某个时间点上的数据集。这种文件非常适合用于进行备份和灾难恢复。

2.生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。

3.RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

②、劣势

1、RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,如果不采用压缩算法(内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑),频繁执行成本过高(影响性能)

2、RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题(版本不兼容)

3、在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值