关于数据备份的个人观点

「数据无价」应该是一个几乎所有人都听过和了解过的事情了,毕竟几乎所有的人都或多或少的遇到过数据丢失的事情。小到遗失手机或是意外损坏导致的数据丢失,大到工作机器意外损坏遗失了重要的工作文件,类似的事情比比皆是。

很多的人往往不在意「数据备份」这件事情,一定要等到真的数据遗失了之后才追悔莫及。有些人甚至在这件事情上面跌过了一次跟头也没有好好反思并采取措施,比如说我自己。我自己曾经因为各种大大小小的问题遗失过数据,但是每次都在载体重建完成后无限拖延「备份」这件事情。

不记得是在吃了多少次亏后,自己开始非常注重资料的备份这件事情。现在我往往是一个新的环境刚刚接手,第一件事情就是把资料备份的操作先处理好了。无论是手机、电脑,还是说 VPS。

个人的 VPS 备份原因

我目前的 VPS 因为只是个人需求,所以只买了一台。但是就仅仅这一台 VPS 上面就托管了很多对于我自己来说非常重要的东西。除了博客程序外,还有开源的密码管理软件 Bitwarden,以及自用的 git 托管平台 Gitea 等等。这些数据万一遗失了,对我的打击应该可以说是毁灭性的了,所以这些数据的备份是优先级最高的事项了。

现在各个平台都有各自适用的备份操作。像是现在,几乎所有的移动平台都内置了自家的备份选项,大家直接在系统设置里面把备份的选项打开就可以享受到方便的备份服务了,但是 PC 和 Server 相对于移动设备来说就复杂的多了,这时候就需要大家配置更加个人化的备份操作了。

VPS 备份的前提

在各类数据分布复杂和相对凌乱的 PC 和 Server,首先要做的是尽量让对自己重要的数据聚合在一个位置,这样更加方便管理。比如我到一家新的公司就职的时候,第一件事情就是要给自己建立一个专门对应当前工作的文件夹,之后工作中新建文件和接手的文件都会在这个文件夹下面根据自己的需求分类存储。这样操作的好处很明显,那就是自己找起来方便,备份数据的时候也方便。

现在除了一些特殊原因需要用 Windows Server 外,应该绝大多数场景下大家应该都是用 Linux Server,的因为我自己有轻微的「系统洁癖」,所以为了避免我的机器上出现太多我不认识的文件散落在各个角落,所以我的 VPS 上面跑的应用,基本都是通过 Docker 在运行,所有重要的数据都映射到了宿主机的一个目录下,这样下来我就只需要管备份那一个目录就可以了。

备份方案的选择

备份的方案特别多,我刚开始对 VPS 进行备份是通过 Dropbox Uploader那时候什么都不懂,只是在网上随便搜索,找到了一个使用这个工具的教程,里面还配了一个脚本文件,脚本的工作顺序式:

  1. 通过 tar.gz 打包文件并根据日期命名压缩文件;
  2. 通过 Dropbox Uploader 把压缩文件上传到 Dropbox 下的对应文件夹里;
  3. 清理 VPS 本地备份产生的压缩文件。

虽然这个方案我用了很长的时间,但是后来还是换了。

一个原因是自己备份的数据量开始变大,使得后来每次备份都需要消耗好几百 MB 的流量,稍微有点费流量;另一个原因就是像是 Bitwarden 这种应用的数据库备份的时间不能拉的太长,万一丢了带 2FA 的密码数据,真的就没有办法找回了。

综上原因,我开始想着换一个新的方式来备份数据。最后我选择了 Rclone。

其实用 Rclone 也有很长一段时间了,不过那时候是用来挂载 Google Drive 到自己的树莓派上,只是为了 Plex 做媒体库来用的,一直也没有想过还能用它来做备份。Anyway,啰嗦半天,现在说说我是怎么用 Rclone 来备份的吧。

Rclone 基本的操作

首先需要在机器上安装和配置好 Rclone,这一部分的操作可以参考这一篇:

Rclone 绑定 Dropbox 和 Google Drive
Rclone 的配置过程对于第一次接触的小白来说可能还是有一点点迷糊的。这边就简单的模拟操作了一下 Rclone 是怎么配置 Dropbox 和 Google Drive 的。

当 Rclone 配置好之后就可以通过各种命令来进行本地和云存储间的文件操作了。

Rclone 的基本操作模式如下:

# 从本地到远程的操作
rclone [命令] <本地路径> <网盘名称:路径> [参数] ...

# 从远程到本地的操作
rclone [命令] <网盘名称:路径> <本地路径> [参数] ...

# 在两个远程目标中互相操作
rclone [命令] <网盘名称:路径> <网盘名称:路径> [参数] ...

功能选项是有很多的,想要深入了解可以参考 官网介绍页,下面介绍几个日常使用的时候会经常使用到的功能:

命令 描述
check 检查源和目标匹配中的文件
move 将文件从源路径移动到目标路径
copy 将文件从源复制到目标,跳过已复制的
sync 把源路径内容同步到目标路径,仅修改目标路径
mount 将远程文件系统挂载在本地上
delete 删除路径中的文件

使用方法很简单,在输入自己需要的命令后,在后面加上源路径和目标路径就可以了。操作远程目标的时候,使用自定义的名字做主机名即可,比如:

# 下面命令中 dropbox 和 gdrive 都是在 rclone config 中自定义的名称

# 通过移动命令将本地 /home/xsnaruto 移动到 Dropbox 的对应路径
rclone move /home/xsnaruto dropbox:/Apps/rclone

# 将 Google Drive 对应路径内容复制到本地的 /home 目录下
rclone copy gdrive:/Backup/TMP /home/

题外话:选择 Dropbox 和 Google Drive 存储备份的理由

有一点想讲一讲,就是为什么我会选择并且推荐使用 Dropbox 和 Google Drive 来存储备份文件。

这这要是因为它们是有提供文件历史版本追溯的功能,当数据可能出现问题的时候,可以直接到它们的网站上面通过历史版本功能找回历史版本文件。

虽然免费用户的历史记录只有追回最近 1 个月内的历史版本文件,但是对于个人使用来说,基本上是完全够用啦。

开始备份 VPS 数据

我的所有需要备份的数据都通过 Docker 映射到了机器根目录下的 www 文件夹中,所以我只需要备份 /www 这个文件夹就可以了。命令我使用的是 rclone sync,这个命令可以扫描对比源路径和目标路径下文件的差异,然后仅对有差异的文件进行操作,这样就可以避免每次备份都要重新备份完整目录,减少流量消耗。

命令和上面复制移动操作一样,没有区别,比如:

# 将本地 /www 的内容同步到 dropbox 下的 /Apps/VPS 中
rclone sync /www dropbox:/Apps/VPS

上面这段命令会先检测 /www 和 Dropbox 下 /Apps/VPS 中文件的差异,然后才会把存在差异的文件同步到 Dropbox 上。

如果想要观看同步过程中的细节,在命令结尾追加一个 -P 参数即可。

过滤文件和文件夹

部分文件比如 log 文件,还有一些缓存文件,这些文件可能不太需要备份,比如我的 VPS 上的一些 log 文件经常加起来能有 100 多 mb,但是去备份中查看 log 文件的机会几乎为零,所以在备份数据的过程中我会排除掉它们。

Rclone 过滤文件和文件夹的方法很简单,只用追加对应参数即可:

参数方法 功能描述
--exclude 排除特定的文件和文件夹
--include 包含特定的文件和文件夹
--filter-from <规则文件> 根据自定义的规则文件来排除和包含特定的文件和文件夹
--delete-excluded 在目标路径下删除源路径下已删除的文件或文件夹

具体的操作方法如下:

# 文件的操作直接追加路径和文件名即可,比如:
--exclude "bitwarden.log" //排除特定的文件

# 使用通配符操作多个同类型文件,比如:
--include "*.{jpg.png}" //包含 jpg 和 png 文件
--exclude "bitwarden/*.log" //排除 bitwarden 下所有 log 的文件

# 需要包含或排除一个文件夹,需要追加一个斜杠 / 来声明其为文件夹
--exclude "tautulli/cache/" //排除 tautulli 下的 cache 文件夹

上面的方法适用于较为简单的需求,如果同时需要排除和包含多种文件和文件夹,可以编写一个规则文件来统一进行管理。Rclone 的过滤规则文件模版如下:

# 每一行为一个规则,加号表示包含,减号表示排除,后面追加具体规则。
+ *.jpg
+ *.png
- .DS_Store
- .log
- /tautulli/Cache/
- /ghost/logs/**

文件命名可以随意,我是将它保存为 filter.txt,同时为了日后可以复用这个规则文件,把它存储到了 /www/tools/rclone/ 中,这样在进行备份操作的时候这个规则文件也同样被备份到远程存储中了。

这时候执行同步操作的时候就只用追加下面的参数就可以了:

--filter-frome "/www/rclone/filter.txt"

执行同步操作备份数据到远端

个人的备份数据会用到的命令就大概介绍完了,最后我的完整备份命令为:

rclone sync /www dropbox:Backups/ImWc.Me --filter-frome /www/docker/tools/Rclone/filter.txt --delete-excluded -P

这个命令将完成的操作是:

  1. 先是对比本地 /www 和 Dropbox 下 Backups/ImWc.Me 文件夹内容的差异;
  2. 配合 /www/docker/tools/Rclone/filter.txt 过滤文件;
  3. 开始传输检测到有差异的文件
  4. 搭配参数 --delete-excluded ,在目标路径下删除本地已经丢弃的内容

个人手动执行命令的时候,可以在结尾追加 -P 观察 Rclone 执行过程。

自动执行备份操作

每次都手动来执行备份操作显然是不现实的,为了数据安全考虑,我们会需要机器定期自动来执行备份的操作,这个就很简单了,直接通过 cron 来自动执行我们上面的指令就行了。

首先在命令行输入 crontab -e 并回车,进入 cron 的配置文件,在结尾处追加自己的 rclone 命令就可以了。比如我的是:

# Rclone backup docker files
0 */12 * * * rclone sync /www dropbox:Backups/ImWc.Me --filter-frome /www/docker/tools/Rclone/filter.txt --delete-excluded
0 */1 * * * rclone sync /www/bitwarden dropbox:Backups/ImWc.Me/bitwarden
 
0 */12 * * * rclone sync /www gdrive:Backup\ Folder/ImWc.Me --filter-frome /www/docker/tools/Rclone/filter.txt --delete-excluded
0 */1 * * * rclone sync /www/bitwarden gdrive:Backup\ Folder/ImWc.Me/bitwarden 

Rclone 的时间配置就不介绍了,我的这段配置里面配置了两个同步目标,一个是 Dropbox,另一个是 Google Drive,双重保险嘛;

开头的 0 */12 * * *0 */1 * * * 分别表示为每 12 小时执行一次命令以及每 1 个小时执行一次。我个人之所以分别执行两次,是因为 12 小时执行一次的是完整的同步操作,而 1 小时执行一次的是单独的 Bitwarden 数据,因为对于我个人而言,Bitwarden 密码库的数据是更改比较频繁,同时数据会比较重要的,所以我单独给它添加了一个每隔 1 小时同步一次的额外指令。这个可以根据自身需求自己设定。

编写完成之后直接保存就行了,正常情况下 cron 会自动重新加载刚刚添加的命令。


这篇不算教程啦,因为太水了,我只是记录一下自己的备份设置而已。Rclone 的功能很多,大家可以查找一下网络上更多针对与 Rclone 使用的介绍文章,如果英文还不错的话,也可以直接在 官网 查看官方的说明,其实官网的英文也不复杂啦。

另外,我还有更多一个备份的命令,是使用 Dropbox Uploader 来进行的每个月一次的完整数据打包备份操作,如果对自己数据有归档操作习惯的可以看看这一篇: