使用 MEGA 来实时备份网站服务器数据

自从前一阵经历了项目服务器和树莓派双双挂掉的事情之后,对数据安全问题更加注意了,把手头的所有数据都尽可能多备份了。最近几天一直在研究集群分布式存储方案,因为目前好多网站都是在一台VPS上,万一哪天这台挂了,得丢好多数据,服务也要挺久不能用的。打造高可用系统一个要求是服务中断时间足够短,一台挂掉了,另外一个能赶快接手,这一点docker swarm就能提供;另外一个是数据安全,如何保证当机之后新实例能在不丢失数据的情况继续服务。

做到数据高可用,一个是把各个服务本身做成高可用,例如Mysql Cluster、Redis slave等等,但是这个需要对原有架构重新设计,工作量比较大。另外一个就是打造可靠的底层存储,通过分布式存储等技术来做,对上层服务来说无感知,这块做了一些调研,常见的有Ceph、GlusterFS等等,也进行了一些尝试,但是都不尽如人意。GlusterFS的问题在于小文件性能太差,严重影响服务速度;而CephFS呢,(高)并发下会有问题,一个是多客户端同时读写同一个对象会造成数据丢失,这个找了文章说是确实没法保证,另外一个是在同一个机器上循环5000次做append操作也会丢失,这个就完全无法接受了,万一上层服务读写速度很快,那这难保不会出现故障,按理说CephFS应该不会出现这个问题,不知道是哪里需要配置什么的。

从N个9到放弃

原本的计划是做无感知自动切换,不过折腾之后没有找到合适的,所以最初的需求就变成了保证当机之后我能很快在其他服务器上手动恢复。这个只需要保证数据实时备份就可以了,当然了,肯定会丢失少量数据的,不过也在可接受范围之内吧。

其实一直是有这一套机制的,服务器部署之初就布上了,用的Dropbox,但是这玩意经常强制升级,想着好久没升级了,把 docker镜像 升级一下,然后就发现令人不爽的事情:上一次备份在三个月之前。。。明明服务是在运行的,看了一下日志,提示 [ALERT]: So your files continue to sync, sign in to your Dropbox account and move Dropbox to a supported file system. ,搜了一下发现是Dropbox又他喵的升级了,现在 在Linux下只支持未加密的 ext4 格式 ,虽然服务器底层文件系统确实是ext4,但是容器里显示的是其他的,所以就无法使用了。看另外一个制作dropbox镜像的哥们也没有解决这个问题,我就不打算继续折腾了,尽管在宿主机上部署dropbox能解决这个问题,但是洁癖如我,是不会允许的。开始想办法迁移到其他平台。

MEGA

当然了,一定要有命令行版本,容量什么的倒无所谓,数据量不是很大。

在对比了 OneDrive、Google Cloud、MEGA等等之后最终选了MEGA,OneDrive 做的太垃圾了,不支持断点续传,之前用桌面客户端上传一个数据集重试了好几次都没成功,再加上教育版本还是有点不太安全,所以目前只是当成下载服务器用;至于Google Cloud,用的不多,容量挺小,而且我Google账号也不是很多,就放弃了。

MEGA这个网盘,感觉挺有意思的,大三的时候网易邮箱的裤子就是从这家下的;而且这家主打安全,数据都会在本地加密再上传,页面上说服务器上没法审查用户数据;其次界面看起来贼喜欢;这家网速也很快,不像OneDrive会限速。

MEGA 唯二的缺点在于一个是老板似乎有点个人问题,另外一个就是感觉毕竟小厂不太稳,不过无所谓了,本身就只是作为备份使用,个人的重要数据还是继续放在Dropbox上的。

Docker 镜像化

本着 all in docker 的原则,做一个MEGA的镜像,遇到一个问题,发现有人提问了,不得不佩服开发者,竟然知道是docker部署遇到的问题,看来docker也一定玩的很溜吧。

按照说明,很快就把镜像做出来了。

Dockerfiles/mega

FROM debian:9-slim

MAINTAINER Newnius 

RUN apt-get update && apt-get install curl gnupg2 -y && \
    curl https://mega.nz/linux/MEGAsync/Debian_9.0/amd64/megacmd-Debian_9.0_amd64.deb --output megacmd.deb && \
    echo path-include /usr/share/doc/megacmd/* > /etc/dpkg/dpkg.cfg.d/docker && \
    apt install ./megacmd.deb -y && \
    rm megacmd.deb && \
    rm -rf /var/lib/apt/lists/*

CMD ["sleep", "infinity"]

同步设置

首先启动 mega

docker run \
    --name mega \
    -d \
    --restart always \
    --cpus 0.2 \
    --mount type=bind,src=/etc/localtime,dst=/etc/localtime,readonly \
    --mount type=bind,src=/home/mega/.megaCmd/,dst=/root/.megaCmd \
    --mount type=bind,src=/data/,dst=/data \
    newnius/mega

这块有几个需要注意的地方。

首先是限制CPU使用率,因为VPS比较低配,同步盘这类突发的CPU会很高,限制一下,免得把服务器搞死了或者长时间高使用率被服务商警告。

然后是挂载容器的 /root/.megaCmd 目录,登陆信息什么的都在这里,不持久化重启之后就需要重新登陆。

最后一个是数据目录。

# 登陆mega账号
docker exec -it mega mega-login $MEGA_EMAIL $MEGA_PWD

这块感觉做的不太好,需要用账号密码登陆,泄漏了就麻烦了,还是Dropbox那种一次性token比较好。建议开启2FA验证,这样即便密码泄漏了也还有第二道屏障,在登陆时添加 --auth-code 参数即可。

# 允许同步隐藏文件
docker exec -it mega mega-exclude -d ".*" --restart-syncs

MEGA 默认会忽略以下几种文件

Thumbs.db
desktop.ini
~*
.*

前面三个倒还好,主要是最后一个,类似apache的 .htaccess 文件是需要的,不能忽略,所以去掉这个限制。

# 新建同步任务
docker exec -it mega mega-sync /data /remote

其中 /data 目录是本地目录, /remote 是远程目录,需要提前新建。

每次重启之后需要重新启动同步任务

docker exec -it mega mega-reload

可以通过命令查看同步状态

docker exec -it mega mega-transfers  --show-syncs

试用了一天,发现同步有一点小问题,新增和删除都很快同步,就是对于同一个文件的变化不能感知到,还需要继续观察。