线上运行的项目,无论大小,重要数据的备份是必须要考虑的事项。比如每天都在产生新数据的数据库。在不考虑「容灾」的前提下,通常可以选择定时复制要备份的数据并保存在项目所在的服务器上,不过使用云存储会是一个更加稳妥的选择。
为什么要云备份
关于容灾这个概念,通常指的是防范数据在一些极端情况下导致的不可逆的灾难性后果。以上面说的在项目服务器上保存备份数据为例,就存在一些大概率会导致备份数据丢失的风险。比如系统升级,或是对项目架构进行调整。在一些需要手动输入命令的场合一个误操作就会导致悲剧发生。
即便是不会发生误操作,在项目备份数据越来越大的时候,这些使用频率不高的备份数据也会无端占用宝贵的项目磁盘空间。而云存储的空间价格通常是要比服务器的磁盘价格便宜的,所以这也是一笔经济账。
云备份方案
我目前的服务器在阿里云,所以这里以阿里云 OSS 为例,先介绍一下我的备份思路和流程。
- 开通阿里云 OSS 服务。选择和自己云服务器同地区的 OSS 存储。
- 创建一个可以调用 OSS 服务的子帐号。
- 在项目服务器上配置好 OSS 帐号,然后通过自定义的备份脚本搭配 crontab 实现定时备份指定数据的功能。
前面两步很简单, 在阿里云后台就可以操作好,最重要的就是第三步。由于阿里云提供了一个可以操作 OSS 的辅助命令,所以最后这步也不是很难。
实现云存储备份
根据上面的方案,我们一步步来实现。
第一步进入阿里云 OSS 服务的界面,然后创建 Bucket。
上面比较重要的选项有两个,分别是地域和存储类型。地域刚才说了, 一定要选择和自己服务器同一个地区的,这样备份数据时才能走内网地址,不会产生额外的流量费用。关于存储类型,越往后,存储费用越便宜。不过要注意最后两个归档类型,它们的费用是最低的,但使用前需要额外的解冻操作。如果没有长时间存储的特殊需求,就没必要选它们两个。我自己用的是「低频访问存储」。
第二步进入阿里云的 RAM 访问控制界面,创建一个用户,并添加访问管理 OSS 对象存储的权限。在这一步的认证管理项中,有一个 AccessKey 的功能,这是等下脚本访问 OSS 时要用到的令牌。完成用户的配置后,再次回到 OSS 的管理界面,进入刚创建的 Bucket,在 Bucket 授权策略中加入刚添加的用户帐号,并指定相应的授权资源。
最后一步。先通过下面的地址下载 OSS 的命令行工具。
我的服务器为 Linux,下载下来的文件名为 ossutil64
。把这个下载的命令文件上传到服务器的 /usr/local/bin/
目录下,并添加可执行权限。然后在服务器用户主目录下创建一个 .ossutilconfig
文件,文件内容如下:
[Credentials]
language=EN
accessKeyID=AccessKey
accessKeySecret=SecretKey
endpoint=oss-cn-hangzhou.aliyuncs.com
其中 accessKeyID
和 accessKeySecret
就是第二步创建用户时可以拿到的。把后面的值替换为相应的内容。endpoint
是 Bucket 内网地址。
接下来就可以使用 ossutil64
命令了。比如复制一个文件到 OSS 上:
ossutil64 cp -f <local-file-path> oss://<bucket-name>/<file-path>
上面 <local file path>
代表本地文件路径,<bucket-name>
代表在 OSS 上创建的 Bucket 名称,<file-path>
是要在 OSS 上存放的文件路径。OSS 文件没有文件目录的概念,所以使用多级目录的地址时不用提前创建目录,这点和使用本地文件系统的方式相比,还是很方便的。
通过命令删除 OSS 上的文件也很方便,命令格式如下:
ossutil64 rm oss://<bucket-name>/<file-path>
以上命令都需要手动来执行,如果想要实现定时自动备份的功能,就需要借助 Linux 服务器上的 Crontab 工具了。类似于 Windows 上的计划任务。设置好排期,结合上面给出的 ossutil64 cp
命令示例,就可以实现定时把文件备份到 OSS 上的功能。
自定义备份命令
使用 ossutil64
默认提供的功能虽然已经可以达成备份目的了,不过我希望更进一步,实现按日期归档备份,并可以指定保留多长时间的备份。这需要自己写点 Shell 代码。
#!/bin/bash
FILENAME=`date +"%Y-%m-%d"`
function savefile {
EXPIRED_FILENAME=`date --date="-$3 day" +"%Y-%m-%d"`
SUFFIX=`echo $1|cut -d"." -f2`
/usr/local/bin/ossutil64 cp -f $1 $2/${FILENAME}.$SUFFIX
/usr/local/bin/ossutil64 rm $2/$EXPIRED_FILENAME.$SUFFIX
}
function syncfolder {
ossutil64 sync $1 $2 -f
}
savefile /project1/database/database.sql oss://my-backup/project1/sql 2
savefile /project2/database/database.sql oss://my-backup/project2/sql 5
syncfolder /project3/uploads oss://my-backup/uploads
上面的脚本定义了两个函数,一个用来根据指定的时长来保留备份文件,一个用来同步目录。代码没几行,逻辑也不复杂,这里就不解释了。结合 Crontab,一个可定时备份,且支持自定义配置保留天数的备份功能达成。