6. 进阶篇:Redis 备份与恢复实战
Redis 之备份与恢复实战
备份与恢复的意义
1.为什么要做备份? 在日常的应用中,无时无刻不充满着危机。服务器down机、磁盘损坏、系统崩溃、数据误操作等等一系列的问题,都在影响着我们的数据安全。备份可以在出现问题时,保障数据的安全或者把数据损失以及业务上损失降到最低。
2.如何做好备份? 既然我们知道了备份的重要性,我们应该怎么样去做好备份呢,这是一个值得研究的问题,什么样策略时得当的,什么样的策略时最符合我们需求的。
3.为什么有主从还要做备份? 好多同学可能会有这样的疑问,主从不就已经是备份了么? 当数据被误操作、前端代码不严谨导致数据被入侵、主库写入出现的脏数据,同样会同步到我们的从库中。所以、一定要做好文件的备份。
4.备份策略如何选择? 开启AOF备份还是RDB备份,这是个问题,哈哈。多长时间来做,是否需要做异地备份等等都是问题。下边我会根据以上的问题,进行一一的解答,以及告诉大家在实战中,如何操作。
Redis备份演练
服务类型 | 角色 | IP | 端口 |
redis- server | Master | 192.168. 188.191 | 6379 |
redis- server | Slave | 192.168. 188.190 | 6379 |
异地备份机 | 192.168. 188.189 |
通过上图我们可以看到目前我们的环境,在主从的情况下,我们增加了一台异地备份的机器。我们后边将通过这个环境给大家演示。
异地备份步骤
1.本地转移文件
2.打包压缩
3.传输至异地备份机
异地备份操作(RDB文件为例)
shell> mkdir -p /usr/local/back_data #创建本地存放备份目录
shell> cp data/dump.rdb /usr/local/back_data/ #拷贝文件到备份目录中
shell> cd /usr/local/back_data/
shell>
shell> tar zcf back_redis_0311.tar.gz ./dump.rdb #对文件进行压缩
shell> scp back_redis_0311.tar.gz 192.168.188.189:/usr/local/back_data/ #对文件进行异地备份
[email protected]'s password:
back_redis_0311.tar.gz 100% 622KB 622.4KB/s 00:00
shell>
shell> ssh 192.168.188.189 'ls /usr/local/back_data/' #验证192.168.188.189上文件是否备份成功
[email protected]'s password:
back_redis_0311.tar.gz
shell>
自动化脚本备份实现
#!/bin/bash
DATA_DIR=/usr/local/redis/data/ #设定redis文件目录
BAKCK_DIR=/usr/local/back_data/ #设定本地备份目录
NOW="$(date -d'+0 day' +'%Y%m%d%H')" #获取当前时间,精确到小时
HOST1=192.168.188.189 #异地备份主机
mkdir -p /usr/local/back_data/$NOW #创建本地目录,按照时间戳区分
cp $DATA_DIR/dump.rdb /usr/local/back_data/$NOW/ #备份redis的rdb文件到本地
cd /usr/local/back_data/$NOW
tar zcf back_$NOW.tr.gz ./dump.rdb #对备份文件进行压缩
set timeout 30 #设定密码输入超时为 30秒
pwd="123456" #设定root密码
/usr/bin/expect <<-EOF
spawn scp back_$NOW.tr.gz root@$HOST1:/usr/local/back_data/ #执行拷贝命令
expect {
"yes/no" {send "yes\r";exp_continue} #如果第一次连接需要输入yes的时候,自动输入yes
"password" {send "$pwd\n"} #自动输入密码
}
expect eof; #结束expect调用
EOF #关闭EOF
exit 0 #退出脚本
定时计划的备份策略
1.Redis的定位,首先确定redis是否作为纯缓存(纯缓存为何还要备份,会有一个缓存雪崩的概念,高级优化我们会讲到),纯缓存的情况下,我们一般每天进行备份 一次即可。如果没配置持久化,需要在备份前执行bgsave 来生成rdb文件后进行备份。(希望大家通过完善脚本来执行,如果实在自己写不了的,可以留言)
2.AOF和RDB的选择 其实在日常的使用中,在数据比较重要时,我们是打开RDB和AOF两种持久化模式,一般进行异地备份的,我们都选择拷贝RDB快照文件作为备份。因为RDB文件是压缩过的比较小,AOF虽然可以通过重写收缩,但是大量备份的时候,还是会消耗较多磁盘。
3.AOF可以作为本地临时紧急恢复的一种手段,AOF文件恢复重启的时候,恢复比较慢,另外AOF可以手动重写,一些能马上发现的错误,我们可以通过自己手动重写AOF来完成数据恢复,例如 flushdb 执行之后,我们可以重写AOF文件,删除这个命令后重启,就可以完成。
4.AOF和RDB恢复对比 在Redis恢复的时候,当两个文件同时在,Redis会优先选择AOF文件,因为一般AOF文件的数据更为完整。但是从恢复时间来看,RDB文件的恢复时间,会优于AOF文件。鱼和熊掌不可兼得,看大家根据实际情况如何选择。
5.通过以上的信息,我们可以判断出如何来选择我们的备份策略了,因为每个应用的场景不一样,所以大家可以通过博主提到这些点,来考虑自身的环境,然后制定符合自己的备份。
AOF恢复演练
通过以上的备份呢,我们可以保障我们的数据安全了。那么我们下边将通过演练实现如何恢复AOF文件的备份。
我们先连接redis之后,执行了FLUSHALL的操作,删除所有数据。(数据大家可以参考之前的python脚本,自己创建 一些)。 需要恢复的时候首先要停止数据库。
编辑AOF文件,AOF文件的工作原理大家应该都有印象,AOF是记录的数据库所有写操作。那么我们通过文件可以看到,执行了两次FLUSHALL的操作,我们通过vim 编辑文件,把最后执行的FLUSHALL的命令删除掉。然后在启动Redis即可。
启动redis服务,并连接服务查看数据已经恢复完成了。
读懂日志很重要,不解释。哈哈!
注意事项:
1.当数据量较大时,或者写入比较频繁的时候,这种恢复方式并不太实用。因为文件写入的太多,而且文件比较大编辑查找需要恢复的数据,比较困难。针对核心数据,或者值得人力成本去做的时候,可以选择。
2.如果提示AOF文件损坏时,我们可以通过Redis附带的 redis-check-aof程序,对需要恢复的AOF文件进行修复,修复完成之后在进行启动恢复。
3.恢复时比较消耗系统资源 ,恢复时redis重新初始化加载数据,恢复时所需内存约为数据当量X2,所以恢复时要保证系统资源。这就是Redis在使用时正常,假如关闭或者做数据恢复重启的时候,无法启动的原因。
RDB文件恢复
模拟环境 首先我们先删除所有数据,并且删除现有的AOF和RDB文件大家按照这个环境模拟即可,这里不在提供详细操作步骤,直接解析结果。
大家注意看图上的操作步骤,尤其要注意操作顺序。为什么我们把数据文件拷贝过来之后,重启了数据库,结果数据还是0呢。这是个值得思考的问题。下边我将为大家揭秘。见证奇迹的时候到了。
揭秘原因
由于我们开启了AOF和RDB持久化,我们在恢复的时候虽然拷贝到rdb的数据,但是Redis重启的时候发现没有AOF文件,会重新创建一个空的AOF文件。启动初始化内存的时候,优先从AOF文件加载,AOF是新创建的空文件,所以我们查到数据就为空,显示数据未恢复。
正确操作步骤
1.修改redis.conf 关闭 appendonly 参数,修改为no 。
2.关闭数据库,避免数据库重写导致重新生成AOF文件。
2.清空data目录。尤其删除AOF文件。
3.拷贝备份的rdb文件到data目录。
5.启动数据库,加载数据完成(根据实际需求,加载完数据后重新打开APPendonly参数即可)