> 数据库 > Redis >

Redis持久化对于故障恢复的意义

本文以单机部署为例进行介绍。
 
1. 生产环境中Redis启动前的配置
生产环境中,要把redis作为一个系统的daemon进程去运行的,每次系统启动,redis进程一起启动。
 
1.1 Redis各文件目录设置
redis的解压目录下,进入utils目录中,找到redis_init_script脚本
将redis_init_script脚本拷贝到linux的/etc/init.d目录中,将redis_init_script重命名为redis_6379,6379是我们希望这个redis实例监听的端口号
修改redis_6379脚本的第6行的REDISPORT,设置为相同的端口号(默认就是6379)
创建两个目录: /etc/redis (存放redis的配置文件) , /var/redis/6379 (存放redis的持久化文件)
修改redis配置文件(默认根目录下,redis.conf),拷贝到/etc/redis目录中,修改名称为6379.conf
修改redis.conf中的部分配置为生产环境
daemonize   yes                             让redis以daemon进程进行
pidfile     /var/run/redis_6379.pid         设置redis的pid文件位置
port        6379                            设置redis的监听端口号
dir         /var/redis/6379                 设置持久化文件的存储位置

 
 
1.2 启动redis,执行脚本
cd /etc/init.d/redis_6379
./redis_6379 start
 

 
1.3 让redis跟随系统启动自动启动
在redis_6379脚本中,最上面,加入两行注释
#chkconfig:2345 90 10
#description: Redis is a persistent key-value database
 

 
执行如下命令设置开机自启
chkconfig redis_6379 on


 
2. 生产环境中Redis持久化配置
  在生产环境中,为了保证Redis中数据的安全性,都要同时开启RDB持久化和AOF持久化。RDB进行数据冷备,AOF做数据热备。
 
2.1 配置RDB持久化机制
在redis.conf文件,也就是我们这里的/etc/redis_6379/6379.conf去配置RDB持久化
 
save 60 1000

 
每隔60s,如果有超过1000个key发生了变更,那么就生成一个新的dump.rdb文件,就是当前redis内存中完整的数据快照,这个操作也被称之为snapshotting,快照也可以手动调用save或者bgsave命令,同步或异步执行rdb快照生成。
 
save可以设置多个,就是多个snapshotting检查点,每到一个检查点,就会去check一下,是否有指定的key数量发生了变更,如果有,就生成一个新的dump.rdb文件。如下配置:
 
save 900 1
save 300 10
save 60 10000
 

 
2.2 基于RDB持久化机制的数据恢复实验
 
1.在redis中保存几条数据,立即停掉redis进程,然后重启redis,看看刚才插入的数据还在不在,为什么?
 
通过redis-cli SHUTDOWN这种方式去停掉redis,其实是一种安全退出的模式,redis在退出的时候会将内存中的数据立即生成一份完整的rdb快照。
 
2.在redis中再保存几条新的数据,用kill -9 粗暴杀死redis进程,模拟redis故障异常退出,导致内存数据丢失的场景
 
这次就发现,redis进程异常被杀掉,数据没有进dump文件,几条最新的数据丢失了
 
3.手动设置一个save检查点, save 5 1 
如果启动报pid已经存在,则先删除/var/run/redis_6379.pid
 
rm -rf redis_6379.pid

 
写入几条数据,等待5秒钟 
停掉redis进程,再重新启动redis,看刚才插入的数据还在不在,这时我们发现数据可以顺利恢复。
 
2.3 配置AOF持久化机制
在redis.conf文件,也就是我们这里的/etc/redis_6379/6379.conf去配置AOF持久化
 
AOF持久化,默认是关闭的,默认打开RDB持久化
# 可以打开AOF持久化机制
appendonly yes  
 

 
打开AOF持久化机制之后,redis每次接收到一条写命令,就会写入日志文件中,当然是先写如os cache的,然后每隔一定时间在fsync一下,可以配置AOF的fsync策略,有三种:always,everysec,no。我们通常都是用everysec,原因我们在上一篇博客中介绍了。
# appendfsync always
appendfsync everysec
# appendfsync no
 

 
配置AOF持久化文件rewrite的配置
auto-aof-rewrite-percentage 100  # 就是当前AOF大小膨胀到超过上次100%,上次的两倍
auto-aof-rewrite-min-size 64mb   # 根据你的数据量来定,16mb,32mb
 

 
而且机制AOF和RDB都开启了,redis重启的时候,也是优先通过AOF进行数据恢复的,因为AOF的比较完整。

 
3. 企业级的数据备份方案
RDB非常适合做冷备,每次生成之后,就不会再有修改了 
使用定时脚本执行备份方案,crontab -e,该命令详情及使用方法请看百度百科。 
数据备份方案
 
写crontab定时调度脚本去做数据备份
每小时都copy一份rdb的备份,到一个目录中去,仅仅保留最近48小时的备份
每天都保留一份当日的rdb的备份,到一个目录中去,仅仅保留最近1个月的备份
每次copy备份的时候,都把太旧的备份给删了
每天晚上将当前服务器上所有的数据备份,发送一份到远程的云服务上去
/usr/local/redis
 
3.1 每小时copy一次备份,删除48小时前的数据
执行命令:crontab -e
 
0 * * * * sh /usr/local/redis/copy/redis_rdb_copy_hourly.sh
1
redis_rdb_copy_hourly.sh
 
#!/bin/sh 
 
cur_date=`date +%Y%m%d%k`
rm -rf /usr/local/redis/snapshotting/$cur_date
mkdir /usr/local/redis/snapshotting/$cur_date
cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_date
 
del_date=`date -d -48hour +%Y%m%d%k`
rm -rf /usr/local/redis/snapshotting/$del_date
 

 
3.2 每天copy一次备份,删除一天前的备份
crontab -e
 
0 0 * * * sh /usr/local/redis/copy/redis_rdb_copy_daily.sh

 
redis_rdb_copy_daily.sh
 
!/bin/sh 
 
cur_date=`date +%Y%m%d`
rm -rf /usr/local/redis/snapshotting/$cur_date
mkdir /usr/local/redis/snapshotting/$cur_date
cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_date
 
del_date=`date -d -1month +%Y%m%d`
rm -rf /usr/local/redis/snapshotting/$del_date
 

 
每天一次将所有数据上传一次到远程的云服务器上去
 
4. 数据恢复方案
如果是redis进程挂掉,那么重启redis进程即可,直接基于AOF日志文件恢复数据,最多就丢一秒的数
 
如果是redis进程所在机器挂掉,那么重启机器后,尝试重启redis进程,尝试直接基于AOF日志文件进行数据恢复 
 
AOF没有破损,也是可以直接基于AOF恢复的。AOF append-only,顺序写入,如果AOF文件破损,那么用redis-check-aof fix修复,但是要注意的是,修复会导致错误的那条语句被删除,进而导致数据丢失。
 
如果redis当前最新的AOF和RDB文件出现了丢失/损坏,那么可以尝试基于该机器上当前的某个最新的RDB数据副本进行数据恢复
 
当前最新的AOF和RDB文件都出现了丢失/损坏到无法恢复,一般不是机器的故障,找到RDB最新的一份备份,小时级的备份可以了,小时级的肯定是最新的,copy到redis里面去,就可以恢复到某一个小时的数据
 

 

(责任编辑:IT)