13.redis持久化-RDB

reids的持久化是重点

reids是内存数据库,如果不讲内存中的数据保存到磁盘上,那么服务一旦出了问题,服务器中的数据库状态也会消失,所以redis提供了持久化!

RDB

在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照中文件直接读到内存中

Redis会到哪都创建(fork),一个子进程来进行持久化,会将数据写入一个临时的文件中,等到持久化过程都结束了,再用这个临时
文件替换上次持久化好的文件。整个过程中,主进程不进行任何的io操作,这就确保了极高的性能。如果需要进行大规模的数据恢复
且对于数据的恢复完整性不是非常的敏感,那么RDB方式比AOF方式更加的高效,RDB的缺点时最后一次持久化后的数据可能会丢失
我们默认使用的是RDB,一般情况下不需要修改整个配置!

RDB保存的文件是:dump.rdb
因为在redis.conf配置文件中配置了rdb的默认文件名称
    dbfilename dump.rdb

在redis.conf配置文件中配置了rdb文件的持久化规则
save 900 1:表示900 秒内如果至少有 1 个 key 的值变化,则保存
save 300 10:表示300 秒内如果至少有 10 个 key 的值变化,则保存
save 60 10000:表示60 秒内如果至少有 10000 个 key 的值变化,则保存

1.在交互模块获取rdb文件的保存路径
    127.0.0.1:6379> config get dir
        1) "dir"
        2) "/data"
    127.0.0.1:6379> config get save
        1) "save"
        2) "60 5"------>意思是60秒内有5个key的值发生了变化,就会触发持久化规则,生成dump.rdb文件
    127.0.0.1:6379> set k1 v1
        OK
    127.0.0.1:6379> set k2 v2
        OK
    127.0.0.1:6379> set k3 v3
        OK
    127.0.0.1:6379> set k4 v4
        OK
    127.0.0.1:6379> set k5 v5
        OK
    会在docker容器的/data目录下生成:dump.rdb文件

RDB 有两种触发方式,分别是自动触发和手动触发

1.自动触发
    在配置文件中配置save策略
    
2.手动触发
    手动触发Redis进行RDB持久化的命令有两种:
        2.1 1、save
          该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。
          显然该命令对于内存比较大的实例会造成长时间阻塞,这是致命的缺陷,为了解决此问题,Redis提供了第二种方式
            当执行save时,会直接生成dump.rdb文件
       2.2 bgsave
          执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。
            具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。
          基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。
          ps:执行执行 flushall 命令,也会产生dump.rdb文件,但里面是空的.

恢复数据

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

停止 RDB 持久化

在redis的客户端上:使用命令将save策略置为空
    config set save " "

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掉的话,就会丢失最后一次快照后的所有修改(数据有丢失)

RDB 自动保存的原理

Redis有个服务器状态结构:
  struct redisService{
         //1、记录保存save条件的数组
         struct saveparam *saveparams;
         //2、修改计数器
         long long dirty;
         //3、上一次执行保存的时间
         time_t lastsave;
    }

    1、首先看记录保存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 数组将会是如下的样子:
2.、dirty 计数器和lastsave 属性
  dirty 计数器记录距离上一次成功执行 save 命令或者 bgsave 命令之后,Redis服务器进行了多少次修改(包括写入、删除、更新等操作)。
   lastsave 属性是一个时间戳,记录上一次成功执行 save 命令或者 bgsave 命令的时间。
  通过这两个命令,当服务器成功执行一次修改操作,那么dirty 计数器就会加 1,而lastsave 属性记录上一次执行save或bgsave的时间,Redis 服务器还有一个周期性操作函数 severCron ,
   默认每隔 100 毫秒(100毫秒检查一次)就会执行一次,该函数会遍历并检查 saveparams 数组中的所有保存条件,只要有一个条件被满足,那么就会执行 bgsave 命令。
  执行完成之后,dirty 计数器更新为 0 ,lastsave 也更新为执行命令的完成时间

 

posted @ 2022-05-25 21:43  努力的达子  阅读(71)  评论(0编辑  收藏  举报