JAVA后台开发_从入门到精通我爱编程

23 redis的持久化

2017-11-30  本文已影响67人  笑Skr人啊

Redis 提供了多种不同级别的持久化方式:

- RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。
- AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。
- Redis 还可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。
你甚至可以关闭持久化功能,让数据只在服务器运行时存在。

了解 RDB 持久化和 AOF 持久化之间的异同是非常重要的, 以下几个小节将详细地介绍这这两种持久化功能, 并对它们的相同和不同之处进行说明。

RDB 快照
    在默认情况下, Redis 将数据库快照保存在名字为 dump.rdb 的二进制文件中。

    你可以对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动保存一次数据集。

    你也可以通过调用 SAVE 或者 BGSAVE , 手动让 Redis 进行数据集保存操作。

    比如说, 以下设置会让 Redis 在满足“ 60 秒内有至少有 1000 个键被改动”这一条件时, 自动保存一次数据集:

    ```
    ################################ SNAPSHOTTING  ################################
    #
    # Save the DB on disk:
    #
    #   save <seconds> <changes>
    #
    #   Will save the DB if both the given number of seconds and the given
    #   number of write operations against the DB occurred.
    #
    #   In the example below the behaviour will be to save:
    #   after 900 sec (15 min) if at least 1 key changed
    #   after 300 sec (5 min) if at least 10 keys changed
    #   after 60 sec if at least 10000 keys changed
    #
    #   Note: you can disable saving completely by commenting out all "save" lines.
    #
    #   It is also possible to remove all the previously configured save
    #   points by adding a save directive with a single empty string argument
    #   like in the following example:
    #
    #   save ""

    save 900 1
    save 300 10
    save 60 10000   # 60 秒内有至少有 10000 个键被改动

    ```
    这种持久化方式被称为快照(snapshot)。

    ##### 快照的运作方式
    当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:
        Redis 调用 fork() ,同时拥有父进程和子进程。
        子进程将数据集写入到一个临时 RDB 文件中。
        当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
        这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益。

    ##### 如何触发RDB快照

        配置文件中默认的快照配置
            冷拷贝后重新使用
                可以cp dump.rdb dump_new.rdb

        命令save或者是bgsave
            Save:save时只管保存,其它不管,全部阻塞
            BGSAVE:Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过lastsave命令获取最后一次成功执行快照的时间
        
        执行flushall命令,也会产生dump.rdb文件,但里面是空的,无意义
    
    ##### 如何恢复
        将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可
        CONFIG GET dir获取目录
    
    ##### 优势
    - RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。
    - RDB 非常适用于灾难恢复(disaster recovery):它只有一个文件,并且内容都非常紧凑。
    -RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
    -RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
    -适合大规模的数据恢复
    -对数据完整性和一致性要求不高
    
    ##### 劣势
    -如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。 虽然 Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率, 但是, 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据。
    -每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。 虽然 AOF 重写也需要进行 fork() ,但无论 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。
    
    ##### 如何停止
        动态所有停止RDB保存规则的方法:redis-cli config set save ""
AOF启动/修复/恢复
    - 正常恢复
        启动:设置Yes,修改默认的appendonly no,改为yes
        将有数据的aof文件复制一份保存到对应目录(config get dir)
        恢复:重启redis然后重新加载
    - 异常恢复
        启动:设置Yes,修改默认的appendonly no,改为yes
        备份被写坏的AOF文件
        修复:
            redis-check-aof --fix进行修复
        恢复:重启redis然后重新加载
上一篇下一篇

猜你喜欢

热点阅读