redis数据冷备,恢复

数据恢复方案
(1)如果是redis进程挂掉,那么重启redis进程即可,直接基于AOF日志文件恢复数据不演示了,在AOF数据恢复那一块,演示了,fsync everysec,最多就丢一秒的数
(2)如果是redis进程所在机器挂掉,那么重启机器后,尝试重启redis进程,尝试直接基于AOF日志文件进行数据恢复, AOF没有破损,也是可以直接基于AOF恢复的, AOF append-only,顺序写入,如果AOF文件破损,那么用redis-check-aof fix
(3)如果redis当前最新的AOF和RDB文件出现了丢失/损坏,那么可以尝试基于该机器上当前的某个最新的RDB数据副本进行数据恢复

当前最新的AOF和RDB文件都出现了丢失/损坏到无法恢复,一般不是机器的故障,人为
rm -rf一下,
/var/redis/bin/drum.rdb文件给删除了
找到RDB最新的一份备份,小时级的备份可以了,小时级的肯定是最新的,copy到redis里面去,就可以恢复到某一个小时的数据

(4) 如果当前机器上的所有RDB文件全部损坏,那么从远程的云服务上拉取最新的RDB快照回来恢复数据

(5) 如果是发现有重大的数据错误,比如某个小时上线的程序一下子将数据全部污染了,数据全错了,那么可以选择某个更早的时间点,对数据进行恢复
举个例子,12点上线了代码,发现代码有bug,导致代码生成的所有的缓存数据,写入redis,全部错了
找到一份11点的rdb的冷备,然后按照上面的步骤,去恢复到11点的数据,不就可以了吗

容灾演练
appendonly.aof + dump.rdb,优先用appendonly.aof去恢复数据,但是我们发现redis自动生成的appendonly.aof是没有数据的
然后我们自己的dump.rdb是有数据的,但是明显没用我们的数据
redis启动的时候,自动重新基于内存的数据,生成了一份最新的rdb快照,直接用空的数据,覆盖掉了我们有数据的,拷贝过去的那份dump.rdb
你停止redis之后,其实应该先删除appendonly.aof,然后将我们的dump.rdb拷贝过去,然后再重启redis
很简单,就是虽然你删除了appendonly.aof,但是因为打开了aof持久化,redis就一定会优先基于aof去恢复,即使文件不在,那就创建一个新的空的aof文件
停止redis,暂时在配置中关闭aof,然后拷贝一份rdb过来,再重启redis,数据能不能恢复过来,可以恢复过来
脑子一热,再关掉redis,手动修改配置文件,打开aof,再重启redis,数据又没了,空的aof文件,所有数据又没了
在数据安全丢失的情况下,基于rdb冷备,如何完美的恢复数据,同时还保持aof和rdb的双开
停止redis,关闭aof,拷贝rdb备份,重启redis,确认数据恢复,直接在命令行热修改redis配置,打开aof,这个redis就会将内存中的数据对应的日志,写入aof文件中
此时aof和rdb两份数据文件的数据就同步了
redis config set热修改配置参数,可能配置文件中的实际的参数没有被持久化的修改,再次停止redis,手动修改配置文件

数据备份及恢复实战
该实战基于上一篇linux系统redis安装步骤[]
需要用到shell脚本
任务: 每小时复制redis的rdb文件至指定文件夹下进行日志归档
在redis创建task目录和rdbkogs目录

mkdir /usr/local/redis/task
 mkdir /usr/local/redis/rdbkogs

在task目录下

  1. 编写脚本
touch redis_rdb_task_hourly.sh
 也可以直接vi 原来没有此文件保存后会生成此文件
 vi redis_rdb_task_hourly.sh
  1. 每小时备份一次 脚本内容
#!/bin/sh
cur_date=date +%Y%m%d%H
rm -rf /usr/local/redis/rdblogs/$cur_date
mkdir /usr/local/redis/rdblogs/$cur_date
cp /usr/local/redis/bin/dump.rdb /usr/local/redis/rdblogs/$cur_date
del_date=date -d -48hour +%Y%m%d%H rm -rf /usr/local/redis/rdblogs/$del_date

解释以上内容相:
#定义一个变量cur_date 等于当前时间 2019082308 年月日时 可以自己定义
#执行命令 删除指定文件夹
#创建指定名称的文件夹
#复制指定文件 到 指定文件夹内
#定义一个变量 等于当前时间-48小时
#删除该时间命名的文件

这样就完成了一个简单的shell脚本
运行该脚本 ./redis_rdb_task_hourly.sh 则会执行以上内容

每天执行一次

vi redis_rdb_task_day.sh
 内容:
 #!/bin/sh
 cur_date=date +%Y%m%d rm -rf /usr/local/redis/rdblogs/$cur_datemkdir /usr/local/redis/rdblogs/$cur_date
cp /usr/local/redis/bin/dump.rdb /usr/local/redis/rdblogs/$cur_date
del_date=date -d -1month +%Y%m%d #删除上一个月的备份
 rm -rf /usr/local/redis/rdblogs/$del_date
  1. 添加定时任务
    执行命令

crontab -e

crontab结构
从左到右依次为:
[分钟] [小时] [每月的某一天] [每年的某一月] [每周的某一天] [执行的命令]

添加如下内容

#每小时备份一次
 0 * * * * sh /usr/local/redis/task/redis_rdb_task_hourly.sh
 #每天备份一次
 0 0 * * * sh /usr/local/redis/redis_rdb_task_day.sh

数据恢复
假设/usr/local/redis/bin/下的dump.rdb被误删
如果没有开启AOF持久化 则直接在/usr/local/redis/rdblogs/目录下找到最新的rdb备份文件,复制一份到/usr/local/redis/bin/目录下

如果开启AOF持久化 则按照容灾演练步骤执行, 其实就是想方设法让最新的备份文件在redis启动时能被读取