redis系列之数据备份与恢复
数据备份
RDB
存储策略
(1)、周期性持久化
(2)、当触发存储时,就会fork产生子进程执行持久化操作
(3)、RDB 文件一旦被创建, 就不会进行任何修改。 当服务器要创建一个新的 RDB 文件时, 它先将文件的内容保存在一个临时文件里面, 当临时文件写入完毕时, 程序才使用 原子地用临时文件替换原来的 RDB 文件。这也就是说, 无论何时, 复制 RDB 文件都是绝对安全的
(4)、RDB存储文件只有一个,在覆盖前最好定期的把旧的RDB文件加密后存储到如阿里云这种云存储中
如何配置
在redis.conf文件中加入
save 60 10000 表示每隔60秒如果有10000个key变化就会生成一次快照,并且新的快照会覆盖原来的快照
可以加多个这种配置,如
save 600 100
save 900 10
优缺点
优点:
非常适合备份
非常适用于灾难恢复
存储性能高:存储数据时,父进程fork出一个子进程,父进程无需执行任何磁盘IO操作
缺点:
出现故障时可能会丢失一定的数据
当备份的数据集比较大时,fork()可能会非常耗时,造成服务器停止处理客户端
RDB备份方案
1、写crontab定时调度脚本去做数据备份
2、每一个小时都copy一份数据到指定目录,仅仅保留最近48小时的备份
3、每天都copy一份当日的数据到指定目录,这个目录记录一个月内的数据
4、每次copy数据的时候,都把太久的数据删除
5、每天晚上把当前的所有数据都copy一份到远程服务,当然可以加密。
每小时copy 一次备份,删除48小时之前的数据的脚本如下:
crontab -e
0 * * * * sh /usr/local/redis/copy/redis_rdb_copy_hourly.sh (这条命令会自动保存在/var/spool/cron/username username表示用户名,如果你是用root登陆操作这条命令的,那username则会是root)
redis_rdb_copy_hourly.sh 文件内容如下
#!/bin/sh
cur_date = 'date + %Y%m%d%H'(注意:这个不是单引号,而是 1前面那个键的点号`)
rm -rf /usr/local/redis/snapshotting/hour/$cur_date
mkdir /usr/local/redis/snapshotting/hour/$cur_date
cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/hour/$cur_date
del_date = 'date -d -48hour + %Y%m%d%H'
rm -rf /usr/local/redis/snapshotting/hour/$del_date
每天copy一份
crontab -e
0 0 * * * sh /usr/local/redis/copy/redis_rdb_copy_dayly.sh
redis_rdb_copy_dayly.sh 文件内容如下
#!/bin/sh
cur_date = 'date + %Y%m%d'
rm -rf /usr/local/redis/snapshotting/day/$cur_date
mkdir /usr/local/redis/snapshotting/day/$cur_date
cp -rf /usr/local/redis/snapshotting/hour /usr/local/redis/snapshotting/day/$cur_date
del_date = 'date -d -30day + %Y%m%d%H'
rm -rf /usr/local/redis/snapshotting/day/$del_date
AOF
存储策略
(1)、对每条命令作为日志,以append-only的模式写入一个日志文件中,即是以追加的形式加入数据而不是覆盖
(2)、everysec:每次对key进行操作将数据存储到OS cache中,每隔一秒时间fsync到磁盘,性能高,上万QPS没问题,默认配置,生产环境也一般配置此项
(3)、always:每次写入一条数据就fsync一次,性能差、吞吐量低
(4)、no:不主动执行fsync,仅仅redis负责将数据写入os cache中就不管了,然后os自己会是不是有自己的策略进行持久化,不可控
(5)、mysql:内存策略,大量磁盘,一两K
(6)、redis:内存,磁盘持久化,一般来说上万QPS没问题
rewrite
AOF数据是递增的形式的,达到一定量后就会淘汰旧的数据,所以有rewrite操作
配置:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
如上一次rewrite是128M,然后继续写,达到了256,即是原来的100%,就有可能会触发一次rewrite,这个是跟min-size比较,即256 >64 则触发一次write
rewrite过程:
(1)、父进程fork一个子进程,并创建一个新的aof文件
(2)、子进程把内存中的数据往新的aof文件中写入数据
(3)、新进入的数据也会往旧的aof文件中写入,然后新的数据从内存中写入新的aof
(4)、删除旧的aof文件
如何配置
在redis.conf配置文件中,把apendonly 改为yes,打开aof存储
配置存储策略appendfsync everysec
文件损坏修复
当文件损坏后可以修复,当然可能会丢失一部分数据
命令:redis-check-aof –-fix filename.aof
优缺点
优点:实时存数据,有最新的数据
缺点:对服务器压力大
RDB 和 AOF 之间的相互作用
1、redis支持同时开启两个存储策略
2、如果rdb正在BGSAVE则AOF不能执行BGREWRITEAOF,反过来也是一样的,他们不能同时持久化,可以防止两个 Redis 后台进程同时对磁盘进行大量的 I/O 操作
3、如果 BGSAVE 正在执行, 并且用户显示地调用 BGREWRITEAOF 命令, 那么服务器将向用户回复一个 OK 状态, 并告知用户, BGREWRITEAOF 已经被预定执行: 一旦 BGSAVE 执行完毕, BGREWRITEAOF 就会正式开始。当 Redis 启动时, 如果 RDB 持久化和 AOF 持久化都被打开了, 那么程序会优先使用 AOF 文件来恢复数据集, 因为 AOF 文件所保存的数据通常是最完整的
REDIS 恢复
当redis宕机后,导致当前数据丢失。需要拿最新备份数据恢复到redis,如果rdb和aof都打开的情况下,要注意一下几点。
1、拷贝dump.rdb文件到redis 数据文件夹下
2、启动redis,此时如果redis同时开启了aof生成策略,redis会先加载aof,如果没有则生成一个aof
3、此时如果get key获取rdb中的备份数据会发现并没有获取到,这是由于redis启动时,基于新的内存重新生成了一个新的rdb文件,覆盖了备份的rdb文件
4、遇到这种情况应该先把aof生成策略先关闭,即把redis.conf文件中的appendonly 改为 no,然后重启redis
5、此时发现可以获取备份中的数据了,确认数据恢复后,这个时候要打开aof必须动态的打开,方法是进入客户端后,输入命令config set appendonly yes
6、确认设置是否成功,config get appendonly,返回yes ,说明已经设置成功,在此确认数据是否恢复,如果已经恢复,再次停止redis
7、然后修改配置文件,把redis.conf文件中的appendonly 改为yes,然后重启redis.
8、启动后,再次确认数据是否已经恢复,发现已经恢复。