Redis那些事儿(二)持久化

Redis提供了两种持久化方式:RDB持久化和AOF持久化

      RDB持久化能在指定的时间间隔对数据进行快照方式的存储,mysql dump也是类似的方式
      AOF持久化则是记录每次对服务器的写操作到日志中,当某个时刻需要进行恢复时,则重新执行日志的完成过程来恢复原始数据,例如mysql的binlog,HBase的HLog也是如此。默认情况下Redis会每秒fsync策略更新写操作。即一旦出现故障,redis最多会丢失1秒的数据。

目录

RDB持久化

AOF持久化(Append Only File)

RDB持久化

      将Redis内存中的数据,完整的生成一个快照(snapshotting),以二进制格式文件(后缀RDB)保存在硬盘当中。当需要进行恢复时,再从硬盘加载到内存中。Redis主从复制,用的也是基于RDB方式,做一个复制文件的传输。
 

1.工作机制

        写时复制 -- copy-on-write)机制,当Redis需要保存dump.rdb 文件时, 服务器执行以下操作:
        Redis 调用forks. 同时拥有父进程和子进程。
        子进程将数据集写入到一个临时RDB 文件中。
        当子进程完成对新RDB 文件的写入时,Redis 用新RDB 文件替换原来的RDB 文件,并删除旧的RDB 文件。

2.触发方式

  •         自动触发:

      通过规则匹配的方式,满足条件时将自动触发持久化操作。
      在redis.conf中配置 save seconds changes    ,即当在一定时间中改变了一定条数据时,则自动触发持久化操作。
      redis默认配置了三条自动触发规则:
                save 900 1      900秒内改变1条数据,自动生成RDB文件
                save 300 10  300秒内改变10条数据,自动生成RDB文件
                save 60 10000     60秒内改变1万条数据,自动生成RDB文件

  •         save:

      手动触发命令,文件策略:新生成一个新的临时文件,当save执行完后,用新的替换老的。

  •         bgsave:

      异步手动触发命令,Redis会fork出一个子进程进行RDB文件的生成。当RDB生成完毕后,子进程再反馈给主进程。fork子进程时也会阻塞,不过正常情况下fork过程都非常快的。而save命令是同步的,会阻塞redis,只有当save命令执行完毕之后才能进行执行下一个命令。

  •         其他触发方式:

       当关闭redis服务时,如执行redis-cli shutdown命令时,也会触发RDB持久化,(注意,如果直接kill redis的进程,会发生数据丢失,因为该操作没有执行持久化操作)。
            当进行主从复制时,也会触发RDB持久化。

3.RDB基本配置

# 配置自动生成规则。一般不建议配置自动生成RDB文件
save 900 1
save 300 10
save 60 10000
# 指定rdb文件名
dbfilename dump.rdb
# bgsave发生错误,是否停止写入
stop-writes-on-bgsave-error yes
# rdb文件采用压缩格式
rdbcompression yes
# 对rdb文件进行校验
rdbchecksum yes
# 指定rdb文件目录
dir ./

4.RDB优点

       1.RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份,比如你可以在每个小时报保存一下过去24小时内的数据,同时每天保存过去30天的数据,这样即使出了问题你也可以根据需求恢复到不同版本的数据集
        2.RDB是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复
        3.RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能
        4.与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些


5.RDB缺点   

        1.如果你希望在redis意外停止工作(例如电源中断)的情况下丢失的数据最少的话,那么RDB不适合你.虽然你可以配置不同的save时间点(例如每隔5分钟并且对数据集有100个写的操作),是Redis要完整的保存整个数据集是一个比较繁重的工作,你通常会每隔5分钟或者更久做一次完整的保存,万一在Redis意外宕机,你可能会丢失几分钟的数据。
        2.RDB需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求.如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度.

AOF持久化(Append Only File)

       即只追加不允许改写文件,在hdfs中和HBase的HLog就是使用这样的方式。

1.持久化策略:

      redis首先会将用户执行的命令刷新到硬盘缓冲区中,然后通过持久化策略让缓冲区中数据持久化到硬盘。
      redis提供三种策略:
            always:即时持久化,正常来说是每当有命令刷新到缓冲区就将持久化到硬盘。也表示每个命令都做持久化。
            everysec(默认):每秒持久化,即让缓冲区的数据每秒持久化到硬盘中。在高写入量的情况下,可以保护硬盘,最多丢失一秒的数据。
            no:刷新策略由系统来决定,时间不确定。


2.AOF日志重写机制

        AOF采用的机制决定随着命令的逐步写入,AOF文件会逐渐变大,这样就会造成一方面恢复时会越来越慢,另一方面许多的命令的都是多余的,只需要保存其结果即可(如对某个key执行了n次修改或自增到n,只需保存当前的值即可,不需要记录所有的操作过程,如果这个n时重写优化的效率越高)
        重写就是把过期的、没用的、重复的以及可以优化的命令,进行化简,从而减少磁盘占用量,最终压缩日志文件的大小,加快数据恢复速度。    


3.AOF对于异常的处理

       服务器可能在程序正在对AOF文件进行写入时停机,如果停机造成了AOF文件出错(corrupt),那么Redis在重启时会拒绝载入这个AOF文件,从而确保数据的一致性不会被破坏。当发生这种情况时,可以用以下方法来修复出错的AOF文件:

  •             为现有的AOF 文件创建一个备份。
  •             使用Redis 附带的redis-check-aof 程序,对原来的AOF 文件进行修复:$ redis-check-aof –fix
  •             (可选)使用diff -u 对比修复后的AOF 文件和原始AOF 文件的备份,查看两个文件之间的不同之处。
  •             重启Redis 服务器,等待服务器载入修复后的AOF 文件,并进行数据恢复。

4.AOF基本配置

# 是否开启aof持久化
appendonly no
# 持久化保存文件名称
appendfilename "appendonly.aof"
# 持久化策略,everysec-每秒持久化,always-每执行一个操作就持久化,no-由系统决定,默认everysec
appendfsync everysec/always/no
# 重写时是否暂停append操作
no-appendfsync-on-rewrite no
# AOF重写增长率,100%表示数据量大小增长一倍时重写
auto-aof-rewrite-percentage 100
# AOF重写最小文件大小,即当小于该大小时暂时认为日志数据量不大,不需要重写
auto-aof-rewrite-min-size 64mb

5.命令

       bgrewriteaof:开启fork子进程进行aof重写
       redis-check-aof  –fix: 修复AOF文件

6. AOF优点

       1.使用AOF 会让你的Redis更加耐久: 你可以使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync.使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据.
        2.AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也也可使用redis-check-aof工具修复这些问题.
        3.Redis 可以在AOF 文件体积变得过大时,自动地在后台对AOF 进行重写: 重写后的新AOF 文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的,因为Redis 在创建新AOF 文件的过程中,会继续将命令追加到现有的AOF 文件里面,即使重写过程中发生停机,现有的AOF 文件也不会丢失。而一旦新AOF 文件创建完毕,Redis 就会从旧AOF 文件切换到新AOF 文件,并开始对新AOF 文件进行追加操作。
        4.AOF文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以Redis 协议的格式保存, 因此AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了FLUSHALL 命令, 但只要AOF 文件未被重写, 那么只要停止服务器, 移除AOF 文件末尾的FLUSHALL 命令, 并重启Redis ,就可以将数据集恢复到FLUSHALL 执行之前的状态。


7.AOF缺点

        1.对于相同的数据集来说,AOF 文件的体积通常要大于RDB 文件的体积。
        2.根据所使用的fsync 策略,AOF 的速度可能会慢于RDB 。在一般情况下, 每秒fsync 的性能依然非常高, 而关闭fsync 可以让AOF 的速度和RDB 一样快, 即使在高负荷之下也是如此。不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。

参考文章:

猜你喜欢

转载自blog.csdn.net/qq_22177809/article/details/81808176