在实际生产中,无论我们多么地小心,意外总是会发生。很多意外是不可控的,如机房停电等。我们该如何备份 Redis 数据,并在遇到意外时把它恢复出来呢?
备份 Redis 数据
在开始介绍前,请提醒自己:一定要备份数据库!
磁盘是会损坏的,云端的实例是会销毁的,因此:没有备份就意味着要承担数据消失在 /dev/null
中的高风险。
备份 RDB
Redis 对于数据备份非常友好,即使在它运行的时候,你也可以拷贝数据库文件。这是因为 RDB 文件一旦生成后就不会再修改,即使修改,它也会使用一个临时文件,并且仅在新的快照写完后,才会自动重命名新快照为“旧文件名”。
这意味着在 Redis 运行时 拷贝 RDB 文件是完全安全的。我们建议你这样做:
- 在你的 server 上创建一个定时任务:每小时生成一个快照,存放到某个目录中;每天也生成一个快照,存放在另一个目录中。
- 每当定时任务运行的时候,使用
find
来确保删除了过时的快照。比如说,你可以删除 48 小时前的每小时快照,也可以删除一两个月前的每日快照。使用日期和时间来命名你的快照,这样容易区分。 - 把 RDB 镜像传输到数据中心以外的地方,至少也要传输到运行 Redis 实例的机器外,最少每天做一次。
备份 AOF
如果你运行的 Redis 实例已经开启了 AOF,你仍然可以完成备份。
Redis 版本 >= 7.0.0
单个 AOF 文件被分为了多个文件,它们存放在同一个目录中,目录名和配置中的 appenddirname
值保持一致。在正常操作中,你只需要拷贝/归档这个目录下的文件就好了。
不过,如果你是在日志重写时操作,你可能会得到一个无效的备份。为了解决这个问题,你必须在备份时禁用 AOF 重写:
- 关闭自动重写:
CONFIG SET auto-aof-rewrite-percentage 0
,同时不要使用BGREWRITEAOF
命令手动开始重写。 - 检查是否正在进行的重写:
INFO persistence
,确保aof_rewrite_in_progress
的值为 0。如果它是 1 的话,你就不得不等待重写完成后再备份了。 - 现在你就可以安全地拷贝
appenddirname
目录的文件了。 - 当备份完成后,重新开启 AOF:
CONFIG SET auto-aof-rewrite-percentage <prev-value>
。
Redis 版本 < 7.0.0
由于所有的日志都在同一个 AOF 文件中,只需要把这个 AOF 文件拷贝一份就好了(就像备份 RDB 那样)。
这个 AOF 文件可能缺少最后的部分,但是 Redis 仍能正常加载它(参见上一篇文章的 AOF 截断 部分)。
操作步骤如下:
- 关闭自动重写:
CONFIG SET auto-aof-rewrite-percentage 0
,同时不要使用BGREWRITEAOF
命令手动开始重写。 - 检查是否正在进行的重写:
INFO persistence
,确保aof_rewrite_in_progress
的值为 0。如果它是 1 的话,你就不得不等待重写完成后再备份了。 - 现在你就可以安全地拷贝
appenddirname
目录的文件了。 - 当备份完成后,重新开启 AOF:
CONFIG SET auto-aof-rewrite-percentage <prev-value>
。
灾备恢复
就 Redis 而言,灾难恢复基本上和备份是一样的,只不过是多了一步:把这些备份文件传输到许多不同的外部数据中心而已。
这样一来,即使是 Redis 在上面运行和生成快照的主数据中心发生故障,数据也仍然是安全的。
我们来看看最有意思的灾备恢复技巧,它不需要很高的投入:
- Amazon S3 和其他类似的服务是实现灾备系统的很好的方式。你只要把你的每日快照或每小时快照加密传输到 S3 上,你可以使用
gpg -c
(对称加密)。请确保你在多处另存了这个密码(比如把这个密码分享给你最重要的组织成员)。推荐多用几个存储服务,进一步提升数据安全性。 - 使用 SCP(它包含在 SSH 里)来传输快照到远端的服务器上。这样做既简单又安全:租一台距离你很远的小型 VPS,为它安装 ssh,然后在你自己的机器上生成一个不带密码短语的 ssh 客户端密钥,最后把它添加到 VPS 的
authorized_keys
文件中。如此操作后,你就可以实现自动传输备份到 VPS 上了。推荐你租用至少两台不同提供商的 VPS,这样更安全。
有一件很重要的事情,那就是请确保在传输完成之后校验文件的大小(它应该和你拷贝的文件一致)。如果你使用 VPS 的话,最好再校验一下 SHA1。
同时,你还需要有个独立的告警系统,以在最新的备份传输失败的时候,得到及时的提醒。
后语
本文是「Redis 持久化」系列的最后一篇文章,如果可能的话,下一个系列将会是~「Redis 复制」~「Redis 使用」。保持关注喔!
参考
本文使用 CC BY-SA 4.0 国际协议 进行许可,欢迎 遵照协议规定 转载。
作者:六开箱
链接:https://lkxed.github.io/posts/redis-persistence-backup-recovery/