redis 两种持久化方式对比以及数据恢复

redis 两种持久化方式以及数据备份与恢复方案

前言

redis提供了数据持久化的方式,提供数据持久化的意义在于数据的恢复、生产环境下的灾难恢复。

本文将会围绕redis的两种持久化方式对于它们的运行机制、注意事项、备份方案以及基于灾难恢复的场景下的数据恢复方案。

RDB和AOF两种持久化方式

RDB方式

RDB持久化会对redis中的数据进行周期性的持久化,生成一份快照文件,存放在配置文件声明的目录下面的dump.rdb文件。在redis配置文件中可以通过配置dir属性来指定持久化文件存放目录。默认情况下RDB持久化是打开的,可以在配置文件中找到如下内容:

save 900 1
save 300 10
save 60 10000

上述命令之的是如果900秒内有1个key发生了变化,生成一份快照文件,如果再300秒内有10个key发生了改变,生成一份快照文件,如果在60秒内有10000个key发生了改变,生成一份快照文件。

save可以设置多个,就是多个snapshotting检查点,每到一个检查点,就会去检查一下,是否有指定的key数量发生变化,如果有就生成一个新的dump.rdb文件

也可以通过save或者bgsave命令同步或异步指定rdb快照生成。

RDB持久化的工作流程
  1. redis根据配置自己尝试生成rdb快照文件
  2. fork一个子进程出来
  3. 子进程尝试将数据写到临时的rdb快照文件中
  4. 完成rdb快照文件的生成之后,就替换之前旧的快照文件

dump.rdb 每次生成一个快照,都会覆盖之前的旧文件。

AOF方式

AOF持久化会记录服务器执行的所有写操作命令,并在redis重启的时候,通过回访AOF文件来还原数据集,文件使用append-only的默认,所有操作都会追加到文件的末尾。当AOF文件体积超出保存数据集状态的情况下,会进行一个重写(rewrite)操作,确保文件不会太大。通常情况下,AOF文件保存的数据及会比RDB文件保存的数据集更完整。

默认情况下AOF持久化是关闭的,通过以下配置开启AOF持久化

appendonly yes

开启后,会在文件存储目录下面生成一个appendpnly.aof文件,开启了AOF之后,redis重启的时候,会优先通过AOF进行数据恢复。

AOF的fsync策略

打开AOF持久化机制之后,redis每次接收到一条写命令,就会写入日志文件中,当然是先写入os cache的,然后每隔一定时间再fsync一下

可以通过配置以下内容来配置AOFfsync策略:

appendfsync everysec

这个属性有3个值可以配置:

  • always每写入一条数据,立即将这个数据对应给的写日志fsync到磁盘上去,性能会变得很差,但是可以确保说每一条数据都不会丢失
  • everysec每秒将os cache中的数据fsync到磁盘,这个最常用,生产环境下一般都使用这种策略,性能很高。
  • no仅仅负责将数据写到os cache就可以了,不进行fsync等待操作系统对这些数据写入磁盘,这种策略,会让我们的数据不可控,因为无法预知操作系统什么时候会把数据刷到磁盘。
AOF的rewrite

redis中的数据是有限的,很多数据可能会自动过期,也有可能会被用户删除,但是这些操作都会被AOF文件记录下来,所有有可能存在AOF文件越来越大的情况,意思就是说,重建数据集根本不需要执行所有AOF记录的命令,为了处理这种情况,会有一种rewrite策略,在redis 2.4之前是需要手动执行BGREWRITEAOF命令来进行重写AOF文件,redis 2.4版本之后提供了自动rewrite的操作。我们可以配置rewrite的策略

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

这两个参数的意思是,最少AOF文件需要达到64mb就会进行重写,重写了之后,当检测到当前的AOP文件增长幅度大于100%,也就是64mb,即当前的AOF文件大小为128mb的时候,就会自动触发对AOF进行重写操作。

rewrite的过程如下:

  • redis fork一个子进程
  • 子进程基于当前内存中的数据,构建日志,开启往一个新的临时AOF文件中写入日志
  • redis主进程,接收到client的写操作,在内存中写入日志,同时新的日志也继续写入旧的AOF文件
  • 子进程完成新的日志文件之后,redis主进程将内存中的新日志再次追加到新的AOF文件中
  • 用新的日志文件替换旧的日志文件
AOF破损文件的修复

如果AOF文件破损了,可以使用redis-check-aof --fix filename命令来修复破损的AOF文件

RDB和AOF的优缺点

RDB持久化的优点

RDB会生成多个数据文件,每个数据文件都表示了某个时刻中redis的数据,这种多数据文件的方式,非常适合做冷备,可以将定时定期RDB文件通过加密后传输到某些云服务上保存,RDB非常适用于灾难恢复,同时在数据集非常的的情况下,恢复速度比AOF更快。RDB在做数据持久化的时候,通过fork一个子进程来工作,父进程无需进行任何IO操作。

RDB持久化的缺点

redis故障的时候,RDB无法尽量避免数据丢失,如果需要在故障的时候尽可能减少数据丢失,那么AOF更适合,一般来说,RDB保存数据有可能5分钟或者更长时间才做一次,这个时候如果redis故障了,那么可能丢失将近5分钟的数据,同时,如果数据集特别大的时候,fork会非常耗时,如果服务器资源比较紧张的情况下,可能会导致对客户端暂停数毫秒甚至数秒的服务。

AOF的优点

AOF可以更好的保障数据不丢失,默认情况下AOF会每隔一秒,通过一个后台线程执行一次fsync操作,所以最多只会丢失1秒的数据,AOF日志文件已append-only模式写入,没有任何磁盘寻址的开销,性能非常高,即使文件损坏了。也可以通过redis提供的工具进行修复。当AOF文件过大的时候,会在后台进行重写,确保日志文件不会过大。

AOF的缺点

同一份数据,通常AOF会比RDB文件更大,AOF开启后,支持的写QPS会比RDB的低,因为AOF一般设置为每秒fsync一次日志文件,其次在数据恢复的时候,会比较慢,做冷备不太适合。

如何选择持久化方式

  • 不要仅仅使用RDB方式,因为那样有可能会导致丢失较多数据
  • 不要仅仅使用AOF方式,因为使用AOF进行数据恢复速度较慢,而且使用RDB生成快照的方式更叫健壮,可以避免AOF这种复杂的备份和恢复机制的bug
  • 综合使用AOFRDB两种持久化机制,用AOF保证数据不丢失,作为数据恢复的第一选择,用RDB来做不同程度的冷备,在AOF文件丢失或者不可用的情况下,可以使用RDB来进行数据恢复。

AOF和RDB同时工作需要注意的点

  • 如果RDB在执行snapshotting操作,那么redis不会执行AOF rewrite,如果redis在执行AOF rewrite,则不会执行RDBsnapshotting
  • 如果RDB在执行snapshotting,此时用户执行BGREWRITEAOF命令,那么会等待RDB执行完毕,再去至执行AOF rewrite
  • 同时有RDB snapshot文件和AOF日志文件,那么redis重启的时候,会优先使用AOF进行数据恢复,因为其中的日志更完整

数据备份方案

  1. 使用crontab定时调度脚本做数据备份,每小时备份一次rdb文件,保存最近48小时的数据
  2. 每天备份一次rdb文件,保留最近一个月
  3. 每天将当前服务器的备份文件保存到云服务商提供的云存储空间保存。

下面是一份示例的代码:

redis_rdb_copy_hourly.sh

#!/bin/sh

# 当前小时
cur_date=`date +%Y%m%d%k`
# 移除备份目录
rm -rf /xxx/$cur_date
# 创建备份目录
mkdir /xxx/$cur_date
# 复制rdb文件到辈分目录
cp /xxx/dump.rdb /xxx/$cur_date

#删除48小时之前的备份文件
del_date=`date -d -48hour +%Y%m%d%k`
rm -rf /xxx/$del_date




redis_rdb_copy_daily.sh

#!/bin/sh 

cur_date=`date +%Y%m%d`
rm -rf /xxx/$cur_date
mkdir /xxx/$cur_date
cp /xxx/dump.rdb /xxx/$cur_date

# 删除旧得备份数据
del_date=`date -d -1month +%Y%m%d`
rm -rf /usr/local/redis/snapshotting/$del_date

数据恢复方案

  1. 如果是redis进程挂掉,那么重启redis进程即可,直接基于AOF日志文件恢复数据
  2. 如果是redis进程所在机器挂掉,那么重启机器后,尝试重启redis进程,尝试直接基于AOF日志文件进行数据恢复,如果AOF文件破损,那么用redis-check-aof fix命令修复
  3. 如果redis当前最新的AOF和RDB文件出现了丢失/损坏,那么可以尝试基于该机器上当前的某个最新的RDB数据副本进行数据恢复
  4. 在数据完全丢失的情况下,基于RDB冷备,完美恢复数据方案:

    • 停止redis
    • 关闭AOF
    • 拷贝RDB备份文件
    • 重启redis
    • 确认数据恢复
    • redis-cli开启AOF(redis config set)
    • 此时AOFRDB两份数据文件数据同步
    • 停止redis
    • 修改配置文件,开启AOF
    • 重启redis
      为何有如此复杂的操作呢?这是因为在删除AOF文件,然后拷贝RDB文件到持久化目录就启动redis的话,如果不关闭AOF,每次启动redis会读取AOF文件,这个时候AOF文件是没有的,redis会自动生成一个空的AOF文件,然后加载到内存中,同时会基于当前内存数据(空的)生成一份RDB文件,会覆盖掉备份的RDB文件。
  5. 如果当前机器上的所有RDB文件全部损坏,那么从远程的云服务上拉取最新的RDB快照回来恢复数据

  6. 如果是发现有重大的数据错误,比如某个小时上线的程序一下子将数据全部污染了,数据全错了,那么可以选择某个更早的时间点,对数据进行恢复

总结

本文介绍了redis的两种持久化方式机制以及它们的优缺点,同时介绍了redis数据的备份与恢复方案。

你可能感兴趣的:(redis)