文章首发:Redis 的长久化、数据备份计划和数据恢复
redis 的长久化
RDB 长久化
redis 会 fork 创立一个子过程来进行长久化。将数据写进一个临时文件,长久化完结之后会替换上一个长久化好的 RDB 文件。在这期间 redis 主过程不会参加长久化,以保障 redis 的高性能。
触发:
- 客户端在执行 shutdown 命令时,如果没有开启 AOF 长久化,那么就会触发 RDB 的长久化。
-
在 redis 的配置文件中有以下默认配置。在一下的条件成立时,就会触发 RDB 的长久化,而且是应用 save 命令实现的。然而 save 命令会阻塞主过程。个别应用 bgsave 命令,会 fork 出一个子过程进行长久化操作。
save 900 1 #after 900 sec (15 min) if at least 1 key changed save 300 10 #after 300 sec (5 min) if at least 10 keys changed save 60 10000 #after 60 sec if at least 10000 keys changed
- 执行 flushall 命令清空内存中的数据时,同时触发长久化,清空磁盘。
长处和毛病
长处:数据恢复比拟快,适宜大规模的数据恢复,适宜当作冷备的计划。
毛病:如果是忽然宕机,失落的数据比拟多。数据量大时,长久化生成快照 RDB 文件会影响 redis 的性能。
AOF 长久化
开启了 AOF 之后,会将所有命令追加到 AOF 缓冲区中,依据对应的写入策略写入到磁盘的 AOF 的长久化文件中。能够说就是 redis 的一个日志文件,外面记录的是 redis 的写操作。然而因为记录的是一条条命令,AOF 文件会收缩的很快,达到一定量的时候,就会触发 rewrite 操作,重写 AOF 文件,来达到压缩的目标(fork 子过程来实现)。
redis 应用单线程响应命令,如果每次写 AOF 文件命令都间接追加到硬盘,那么性能瓶颈齐全取于以后硬盘负载。先写入缓冲区 aof_buf 中,还有另一益处,redis 能够提供多种缓冲区同步硬盘的策略,在性能和安全性方面做出衡量。
触发:
- redis 的配置文件中默认是没有开启 AOF 的,要开启在配置文件中关上即可
appendonly no
—>appendonly yes
。也能够在 redis 曾经运行时设置:CONFIG SET appendonly yes
,不过这样当 redis 重启时,设置会生效。 -
配置的写入策略触发。
appendfsync everysec
(默认):每秒同步一次命令到 AOF 长久化文件中,效率很高,可能会失落 1 秒的数据。appendfsync no
:从不同步,只需将数据交给操作系统即可。更快,更不平安的办法。通常,Linux 将应用此配置每 30 秒刷新一次数据,但这取决于内核的准确调整。appendfsync always
:每次触发数据变更的时候立刻追加到 AOF 文件中,效率很低,然而很平安。
重写机制:
-
默认配置。比如说上一次 AOF rewrite 之后,是 128mb。而后就会接着 128mb 持续写 AOF 的日志,如果发现增长的比例,超过了之前的 100%,256mb,就可能会去触发一次 rewrite。然而此时还要去跟 min-size,64mb 去比拟,256mb > 64mb,才会去触发 rewrite。
因为 AOF 文件的重写会 fork 出一个子过程进行重写,为了缩小重写次数须要调大上面的参数,然而都是要基于本身应用的 redis 的寄存的数据量来决定。
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
长处和毛病:
长处:以更好的爱护数据不失落,个别 AOF 会每隔 1 秒(默认的同步策略),通过一个后盾线程执行一次 fsync 操作,最多失落 1 秒钟的数据。
AOF 日志文件以 append-only 模式写入,所以没有任何磁盘寻址的开销,写入性能十分高,而且文件不容易破损,即便文件尾部破损,也很容易修复(应用 redis 提供的工具能够修复:redis-check-aof --fix
)。
日志文件即便过大的时候,呈现后盾重写操作,也不会影响客户端的读写。因为在 rewrite log 的时候,会对其中的领导进行压缩,创立出一份须要复原数据的最小日志进去。再创立新日志文件的时候,老的日志文件还是照常写入。当新的 merge 后的日志文件 ready 的时候,再替换新老日志文件即可。
AOF 日志文件的命令通过十分可读的形式进行记录,这个个性非常适合做灾难性的误删除的紧急复原。比方某人不小心 用 flushall 命令清空了所有数据 ,只有这个时候后盾rewrite 还没有产生,那么就能够立刻 拷贝 AOF 文件 , 将最初一条 flushall 命令给删了,而后再将该 AOF 文件放回去,就能够通过复原机制,主动复原所有数据
毛病:对于同一份数据来说,AOF 日志文件通常比 RDB 数据快照文件更大。
AOF 开启后,反对的写 QPS 会比 RDB 反对的写 QPS 低,因为 AOF 个别会配置成每秒 fsync 一次日志文件,当然,每秒一次 fsync,性能也还是很高的。
相似 AOF 这种较为简单的基于命令日志 /merge/ 回放的形式,比基于 RDB 每次长久化一份残缺的数据快照文件的形式,更加软弱一些,容易有 bug。不过 AOF 就是为了防止 rewrite 过程导致的 bug,因而每次 rewrite 并不是基于旧的指令日志进行 merge 的,而是基于过后内存中的数据进行指令的从新构建,这样健壮性会好很多。
RDB 和 AOF 到底该如何抉择
- 不要仅仅应用 RDB,因为那样会导致你失落很多数据
- 也不要仅仅应用 AOF,因为那样有两个问题,第一,你通过 AOF 做冷备,没有 RDB 做冷备,来的复原速度更快; 第二,RDB 每次简略粗犷生成数据快照,更加强壮,能够防止 AOF 这种简单的备份和复原机制的 bug
- 综合应用 AOF 和 RDB 两种长久化机制,用 AOF 来保证数据不失落,作为数据恢复的第一抉择; 用 RDB 来做不同水平的冷备,在 AOF 文件都失落或损坏不可用的时候,还能够应用 RDB 来进行疾速的数据恢复
所以说成年人,全都要!
AOF 和 RDB 同时工作:
- 如果 RDB 在执行 snapshotting 操作,那么 redis 不会执行 AOF rewrite; 如果 redis 再执行 AOF rewrite,那么就不会执行 RDB snapshotting
- 如果 RDB 在执行 snapshotting,此时用户执行 BGREWRITEAOF 命令,那么等 RDB 快照生成之后,才会去执行 AOF rewrite
- 同时有 RDB snapshot 文件和 AOF 日志文件,那么 redis 重启的时候,会优先应用 AOF 进行数据恢复,因为其中的日志更残缺
redis 长久化文件加载流程
- 首先是会去判断是否开启了 AOF,如果存在存在 AOF 文件,则间接加载 AOF 文件
- 如果找不到 AOF 文件,则间接启动,不会加载 RDB 文件
- 如果没有开启 AOF,会去加载 RDB 文件,通过 RDB 复原数据
数据备份计划
- 写 crontab 定时调度脚本去做数据备份
- 每小时都 copy 一份 rdb 的备份,到一个目录中去,仅仅保留最近 48 小时的备份
- 每天都保留一份当日的 rdb 的备份,到一个目录中去,仅仅保留最近 1 个月的备份
- 每次 copy 备份的时候,都把太旧的备份给删了(是否删除旧的备份,看具体情况而定)
- 每天晚上将以后服务器上所有的数据备份,发送一份到近程的云服务器 (用于寄存备份即可,也能够寄存在本地) 下来。
每小时备份一次:redis_rdb_backup_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
# 备份发送到备份服务器,留神免明码登录
# scp -rq /var/redis/6379/dump.rdb root@192.168.129.100:/opt
# 删除最近 48 小时的 rdb 文件
del_date=`date -d -48hour +%Y%m%d%k`
rm -rf /usr/local/redis/snapshotting/$del_date
每小时执行一次该脚本:0 0 * * * ? sh /usr/local/redis/shell/redis_rdb_backup_hourly.sh
每天备份一次:redis_rdb_backup_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 -1day +%Y%m%d`
rm -rf /usr/local/redis/snapshotting/$del_date
每天执行一次备份脚本:0 0 0 * * ? sh /usr/local/redis/shell/redis_rdb_backup_daily.sh
数据恢复计划
(1)如果是 redis 过程挂掉,那么重启 redis 过程即可,间接基于 AOF 日志文件复原数据
(2)如果是 redis 过程所在机器挂掉,那么重启机器后,尝试重启 redis 过程,尝试间接基于 AOF 日志文件进行数据恢复。AOF 没有破损,也是能够间接基于 AOF 复原的。AOF append-only,程序写入,如果 AOF 文件破损,那么用 redis-check-aof fix
(3)如果 redis 以后最新的 AOF 和 RDB 文件呈现了失落 / 损坏,那么能够尝试基于该机器上以后的某个最新的 RDB 数据正本进行数据恢复。
以后最新的 AOF 和 RDB 文件都呈现了失落 / 损坏到无奈复原,个别不是机器的故障,人为。那就把破损的文件给删除了。去备份服务器找到 RDB 最新的一份备份,小时级的备份能够了,小时级的必定是最新的,copy 到 redis 外面去,就能够复原到某一个小时的数据
进行 redis,敞开 aof,拷贝 rdb 备份,重启 redis,确认数据恢复,间接在命令行热批改 redis 配置,关上 aof,这个 redis 就会将内存中的数据对应的日志,写入 aof 文件中
此时 aof 和 rdb 两份数据文件的数据就同步了
redis config set 热批改配置参数,可能配置文件中的理论的参数没有被长久化的批改,再次进行 redis,手动批改配置文件,关上 aof 的命令,再次重启 redis
(4)如果以后机器上的所有 RDB 文件全副损坏,那么从近程的云服务上拉取最新的 RDB 快照回来复原数据
(5)如果是发现有重大的数据谬误,比方某个小时上线的程序一下子将数据全副净化了,数据全错了,那么能够抉择某个更早的工夫点,对数据进行复原
举个例子,12 点上线了代码,发现代码有 bug,导致代码生成的所有的缓存数据,写入 redis,全副错了
找到一份 11 点的 rdb 的冷备,而后依照下面的步骤,去复原到 11 点的数据。