zoukankan      html  css  js  c++  java
  • 探究Redis两种持久化方式下的数据恢复

        对长期奋战在一线的后端开发人员来说,都知道redis有两种持久化方式RDB和AOF,虽说大家都知道这两种方式大概运作方式,但想必有实操的人不会太多。

        这里是自己实操两种持久化方式的一点点记录。 

        先看以下摘录自redis官网原文解释(原文是English,这里用google翻译。)

     Redis持久性

     Redis提供了不同的持久性选项范围:

     

     RDB持久性按指定的时间间隔执行数据集的时间点快照。

     AOF持久性会记录服务器接收的每个写入操作,这些操作将在服务器启动时再次播放,以重建原始数据集。 使用与Redis协议本身相同的格式记录命令,并且仅采用追加方式。 当日志太大时,Redis可以在后台重写日志。

     如果希望,只要您的数据在服务器运行时就一直存在,则可以完全禁用持久性。

     可以在同一实例中同时合并AOFRDB 请注意,在这种情况下,当Redis重新启动时,AOF文件将用于重建原始数据集,因为它可以保证是最完整的。

     要理解的最重要的事情是RDBAOF持久性之间的不同权衡。 让我们从RDB开始:

     

     RDB的优势

     RDBRedis数据的非常紧凑的单文件时间点表示。 RDB文件非常适合备份。 例如,您可能希望在最近的24小时内每小时存档一次RDB文件,并在30天之内每天保存一次RDB快照。 这使您可以在发生灾难时轻松还原数据集的不同版本。

     RDB对于灾难恢复非常有用,它是一个紧凑的文件,可以传输到远程数据中心或Amazon S3(可能已加密)上。

     RDB最大限度地提高了Redis的性能,因为Redis父进程为了持久化所需要做的唯一工作就是分叉一个孩子,其余的都将做。 父实例将永远不会执行磁盘I / O或类似操作。

     与AOF相比,RDB允许大型数据集更快地重启。

      

     RDB的缺点

     如果您需要在Redis停止工作(例如断电后)的情况下最大程度地减少数据丢失的机会,则RDB不好。 您可以在生成RDB的位置配置不同的保存点 (例如,在至少五分钟之后,对数据集进行100次写入,但是您可以有多个保存点)。

     但是,通常会每隔五分钟或更长时间创建一次RDB快照,因此,如果Redis出于任何原因在没有正确 关闭的情况下停止工作,则应该准备丢失最新的数据分钟。

     RDB需要经常使用fork()才能使用子进程将其持久化在磁盘上。 如果数据集很大,Fork()可能很耗时,并且如果数据集很大且CPU性能不佳,则可能导致Redis停止为客户端服务几毫秒甚至一秒钟。 AOF还需要fork(),但您可以调整要重写日志的频率,而无需在持久性上进行权衡。

     

     AOF的优势

     使用AOF Redis更加持久:您可以有不同的fsync策略:完全没有fsync,每秒fsync,每个查询fsync 使用默认策略fsync时,每秒的写入性能仍然很好(fsync是使用后台线程执行的,并且在没有进行fsync的情况下,主线程将尽力执行写入操作。)但是您只能损失一秒钟的写入时间。

     AOF日志仅是一个追加日志,因此,如果断电,也不会出现寻道或损坏问题。 即使由于某种原因(磁盘已满或其他原因)以半写命令结束日志,redis-check-aof工具也可以轻松修复它。

     Redis太大时,Redis可以在后台自动重写AOF 重写是完全安全的,因为Redis继续追加到旧文件时,会生成一个全新的文件,其中包含创建当前数据集所需的最少操作集,一旦准备好第二个文件,Redis会切换这两个文件并开始追加到新的那一个。

     AOF以易于理解和解析的格式包含所有操作的日志。 您甚至可以轻松导出AOF文件。 例如,即使您使用FLUSHALL命令刷新了所有错误文件 ,如果在此期间未执行任何日志重写操作,您仍然可以保存数据集,只是停止服务器,删除最新命令并重新启动Redis

     

     AOF的缺点

     对于相同的数据集,AOF文件通常大于等效的RDB文件。

     根据确切的fsync策略,AOF可能比RDB慢。 通常,在将fsync设置为每秒的情况下,性能仍然很高,并且在禁用fsync的情况下,即使在高负载下,它也应与RDB一样快。 即使在巨大的写负载情况下,RDB仍然能够提供有关最大延迟的更多保证。

     

     过去,我们在特定命令中遇到过罕见的错误(例如,其中有一个涉及阻塞命令,例如BRPOPLPUSH ),导致生成的AOF在重载时无法重现完全相同的数据集。

     这些错误很少见,我们在测试套件中进行了测试,自动创建了随机的复杂数据集,然后重新加载它们以检查一切是否正常。 但是,RDB持久性几乎是不可能的。 更明确地说:Redis AOF通过增量更新现有状态来工作,就像MySQLMongoDB一样,而RDB快照一次又一次地创建所有内容,从概念上讲更健壮。

     但是 1应该注意的是,每次Redis重写AOF时,都会从数据集中包含的实际数据开始从头开始重新创建AOF,与始终附加AOF文件相比(或重写后的读数),对错误的抵抗力更强旧的AOF,而不是读取内存中的数据)。

            2)我们从未收到过有关真实环境中检测到的AOF损坏的用户报告。

     

        以上所述就是RDB会根据配置文件的配置信息定时全量备份时间点的数据; AOF则是根据同步策略追加写入备份文件。

       一. RDB快照持久化

    #首先我们看下配置文件的信息
    [root@guangzhou data]# systemctl status redis
    ● redis.service - Redis 6379
       Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled)
       Active: active (running) since 六 2020-01-18 16:26:42 CST; 18h ago
      Process: 344 ExecStop=/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379 -a jcon shutdown (code=exited, status=0/SUCCESS)
      Process: 348 ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf (code=exited, status=0/SUCCESS)
     Main PID: 349 (redis-server)
       CGroup: /system.slice/redis.service
               └─349 /usr/local/redis/bin/redis-server *:6379
    
    1月 18 16:26:42 guangzhou systemd[1]: Starting Redis 6379...
    1月 18 16:26:42 guangzhou systemd[1]: Started Redis 6379.
    
    #更改/usr/local/redis/etc/redis.conf中配置
    #10秒钟内2次更改写入RDB二进制文件
    save 10 2
    # RDB持久化文件名
    dbfilename dump.rdb
    
    # 数据持久化文件存储目录
    dir /usr/local/redis/data
    
    # bgsave发生错误时是否停止写入,通常为yes
    stop-writes-on-bgsave-error yes
    
    # rdb文件是否使用压缩格式
    rdbcompression yes
    
    # 是否对rdb文件进行校验和检验,通常为yes
    rdbchecksum yes

    #重启redis
    [root@guangzhou data]# systemctl restart redis

    #为便于观察先把redis数据清空,生产环境请慎重.

      127.0.0.1:6379> flushdb
      OK
      127.0.0.1:6379> keys *
      (empty list or set)

     

      #操作前清空RDB文件

      [root@guangzhou data]# pwd && ll

      /usr/local/redis/data
      总用量 0

     

     #set两条数据

     127.0.0.1:6379> set a 100

     OK
     127.0.0.1:6379> set b 200
     OK

     #重命名RDB文件

     [root@guangzhou data]# pwd && mv dump.rdb dump.rdb2 && ll
     /usr/local/redis/data
     总用量 4
     -rw-r--r-- 1 root root 108 1月  19 15:42 dump.rdb2

     #再次set两条数据

     127.0.0.1:6379> set c 300
     OK
     127.0.0.1:6379> set d 400
     OK

     #查看RDB文件,可以发现新的dump.rdb文件大于dump.rdb2,因为RDB是全量备份,dump.rdb比dump.rdb2多了key=c和key=d

     [root@guangzhou data]# ll

     总用量 8
     -rw-r--r-- 1 root root 120 1月 19 16:59 dump.rdb
     -rw-r--r-- 1 root root 108 1月 19 15:42 dump.rdb2

     #现在我们将文件重命名

     [root@guangzhou data]# pwd && mv dump.rdb dump.rdb3 &&  ll
     /usr/local/redis/data
     总用量 8

     -rw-r--r-- 1 root root 108 1月 19 15:42 dump.rdb2
     -rw-r--r-- 1 root root 120 1月 19 16:59 dump.rdb3

     #清空数据

     127.0.0.1:6379> flushdb
     OK

     #停止redis服务

     [root@guangzhou data]# systemctl stop redis

     #删除最新生成的rdb文件,重命名仅含有key=a和key=b的dump.rdb2为dump.rdb

     [root@guangzhou data]# pwd && rm -rf dump.rdb && mv dump.rdb2 dump.rdb && ll
     /usr/local/redis/data
     总用量 8
     -rw-r--r-- 1 root root 108 1月 19 15:42 dump.rdb
     -rw-r--r-- 1 root root 120 1月 19 16:59 dump.rdb3

     #重启redis服务(正常的话重启后redis仅含有key=a和key=b两个数据)

     [root@guangzhou data]# systemctl restart redis
     [root@guangzhou data]#

     #重连redis列出所有key,果然如我们所料,只有a和b

     127.0.0.1:6379> keys *
     1) "a"
     2) "b"
     127.0.0.1:6379>

     #如果对数据完整性要求较高,可以采用RDB快照,启用定时任务备份指定时间点的数据文件,这样一旦发生生产事故,可以很方便数据回滚;另外单个RDB二进制文件,方便文件分散存储,数据迁移挪到其他服务器。

         二. AOF方式持久化

    #更改/usr/local/redis/etc/redis.conf中配置
    #注释上面RDB快照持久方式的配置,并更改aof配置
    
    #开启AOF日志追加
    appendonly yes
    #日志追加的文件名
    appendfilename "appendonly.aof"
    #写入频率,为了便于观察,这里使用更新立即更新日志文件
    appendfsync always
    
    #redis服务重启
    [root@guangzhou etc]# systemctl restart redis
    [root@guangzhou etc]# systemctl status redis
    ● redis.service - Redis 6379
       Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled)
       Active: active (running) since 一 2020-01-20 15:40:17 CST; 9s ago
      Process: 5493 ExecStop=/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379 -a jcon shutdown (code=exited, status=0/SUCCESS)
      Process: 5497 ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf (code=exited, status=0/SUCCESS)
     Main PID: 5498 (redis-server)
       CGroup: /system.slice/redis.service
               └─5498 /usr/local/redis/bin/redis-server 127.0.0.1:6379
    
    1月 20 15:40:17 guangzhou systemd[1]: Starting Redis 6379...
    1月 20 15:40:17 guangzhou systemd[1]: Started Redis 6379.
    
    #转到/usr/local/redis/data目录,自动生成空文件,appendonly.aof
    [root@guangzhou data]# ll
    总用量 0
    -rw-r--r-- 1 root root 0 1月  20 15:42 appendonly.aof
    
    #命令行下录入数据
    127.0.0.1:6379> keys *
    (empty list or set)
    127.0.0.1:6379> set a 1
    OK
    127.0.0.1:6379> set b 2
    OK
    127.0.0.1:6379> set c 3
    OK
    127.0.0.1:6379>
    
    #打印日志文件
    [root@guangzhou data]# ll
    总用量 8
    -rw-r--r-- 1 root root 104 1月  20 15:43 appendonly.aof
    [root@guangzhou data]# cat appendonly.aof
    *2
    $6
    SELECT
    $1
    0
    *3
    $3
    set
    $1
    a
    $1
    1
    *3
    $3
    set
    $1
    b
    $1
    2
    *3
    $3
    set
    $1
    c
    $1
    3
    #文件输出可见每次操作详情,
    #现在我们模拟异常情况,先重命名appendonly.aof文件为appendonly.aof2,停止redis服务
    [root@guangzhou data]# pwd && mv appendonly.aof appendonly.aof2 && systemctl stop redis && rm -rf ./appendonly.aof && ll
    /usr/local/redis/data
    总用量 8
    -rw-r--r-- 1 root root 104 1月  20 15:43 appendonly.aof2
    #在更改appendonly.aof2文件中c的数值为999, appendonly.aof2重命名为appendonly.aof,重启redis服务
    127.0.0.1:6379> keys *
    1) "c"
    2) "b"
    3) "a"
    127.0.0.1:6379> get c
    "993"
    #可见key=c的数据已改变
    $3
    set
    $1
    c
    $3(更改时这里需要从1变为3)
    993

     生产环境我们可以RDB快照和AOF两种方式结合起来使用,RDB快照文件可以定时备份

    注意:

    1)    auto-aof-rewrite-percentage 100

         auto-aof-rewrite-min-size 64mb

        意思启用AOF时,redis会在AOF比上次完成重写AOF时的容量大至少100%时开启一个BGREWRITEAOF,并且AOF容量至少在64MB时发生;

    2)  只配置 AOF ,重启时加载 AOF 文件恢复数据

        同时配置了 RDB 和 AOF ,启动是只加载 AOF 文件恢复数据

        只配置 RDB,启动是将加载 dump 文件恢复数据

    3) 命令行下save命令保存当前时间点全量数据快照, bgsave异步保存快照  

  • 相关阅读:
    【crontab】误删crontab及其恢复
    New Concept English there (7)
    New Concept English there (6)
    New Concept English there (5)
    New Concept English there (4)
    New Concept English there (3)
    New Concept English there (2)Typing speed exercise
    New Concept English there (1)Typing speed exercise
    New Concept English Two 34 game over
    New Concept English Two 33 94
  • 原文地址:https://www.cnblogs.com/wscsq789/p/12209993.html
Copyright © 2011-2022 走看看