完整数据备份至 Amazon S3

完整数据备份至 Amazon S3

我在 Digital Ocean 上托管了一个 Ubuntu 服务器,其规模已经超出了现有的备份解决方案的承受范围。

我使用的堆栈的相关部分是 Node.js、MongoDB 和 Elasticsearch。

到目前为止,备份是通过转储整个 MongoDB 数据库、保存 ES 配置以及复制应用程序目录中的所有其他文件(日志、代码本身等)来完成的。如果是月初,则还会复制所有用户文件,否则仅添加自月初以来更改的文件。然后将所有这些压缩到一个文件中并上传到 Amazon S3。

数据大小已达到该过程占用过多磁盘空间的程度,并且文件无法一次性上传到 S3。

这种规模的应用程序的下一个级别是什么(8 GB 的用户文件、125,000 个用户、3,000 个其他文档,全部可以在 ES 中搜索)?

我知道 Server Fault 上不允许问基于意见的问题。我不是在征求意见,而是在问对于这种规模的应用程序来说,什么是正常且经济有效的解决方案。

更新:这些是我尝试使用 Duplicity 的脚本和配置的相关部分。我使用 Node 来管理备份,因为它适合我现有的日志解决方案,已安排在活动较少的时间与其他所有内容保持一致,并且可以在操作系统之间移植。

节点脚本,日志记录当然需要改进:

// Walks a directory recursively and returns a flat list of files
function walkDir() {};

// Node based rm -rf
function rmrf() {};

exec("mongodump --out dump", { cwd: process.cwd() }, function(err, dta) {
    if (err) return log("Error backing up: couldn't dump MongoDB!");

    exec("sudo duply ats backup", function(err) {
        if (err) log("Error running Duplicity");
        else rmrf("dump");

        log("Exiting.");

        process.exit();
    });
});

重复配置:

GPG_PW='GPG password'

TARGET='s3://s3-us-east-1.amazonaws.com/bucket'

TARGET_USER='Known working AWS credentials'
TARGET_PASS='AWS secret key'

SOURCE='/var/appdir'

MAX_AGE=6M

DUPL_PARAMS="$DUPL_PARAMS --exclude "/var/appdir/elasticsearch/data/**" "

我已尝试过--s3-use-new-style、使用s3+http://和设置S3_USE_SIGV4,但没有成功。

这是我从 Duplicity 获得的日志:

Start duply v1.5.10, time is 2015-07-05 09:30:13.
Using profile '/root/.duply/ats'.
Using installed duplicity version 0.6.23, python 2.7.6, gpg 1.4.16 (Home: ~/.gnu                                                                     pg), awk 'GNU Awk 4.0.1', bash '4.3.11(1)-release (x86_64-pc-linux-gnu)'.
Signing disabled. Not GPG_KEY entries in config.
Test - Encryption with passphrase (OK)
Test - Decryption with passphrase (OK)
Test - Compare (OK)
Cleanup - Delete '/tmp/duply.25562.1436103014_*'(OK)

--- Start running command PRE at 09:30:14.155 ---
Skipping n/a script '/root/.duply/ats/pre'.
--- Finished state OK at 09:30:14.183 - Runtime 00:00:00.027 ---

--- Start running command BKP at 09:30:14.208 ---
Reading globbing filelist /root/.duply/ats/exclude
BackendException: No connection to backend
09:31:27.427 Task 'BKP' failed with exit code '23'.
--- Finished state FAILED 'code 23' at 09:31:27.427 - Runtime 00:01:13.218 ---

--- Start running command POST at 09:31:27.465 ---
Skipping n/a script '/root/.duply/ats/post'.
--- Finished state OK at 09:31:27.491 - Runtime 00:00:00.026 ---

答案1

我有使用以下方法备份的丰富经验表里不一。如果您能够创建快照并以只读方式挂载它,那么进行一致的增量备份是一个非常好的选择。

通常,备份数据库(MongoDB、ElasticSearch、MySQL,随便什么都可以)的问题在于一致性。备份常见文件也存在同样的问题,但对于数据库来说,数据损坏的风险可能是最高的。

你的选择很少(希望其他人能增加更多)

  1. 转储数据库并备份转储。这是最简单、最安全和最直接的方法。

  2. 停止数据库(或使用其他方法使磁盘上的数据一致)并进行备份。(这样会导致长时间停机,并非总是可能的)

  3. 停止数据库(如 #2 所示),创建快照(卷或 fs,确保 fs 此时一致),启动数据库,以只读方式挂载快照并备份。但并非所有设置都适合此操作。

  4. 停止数据库(如 #2 所示),创建快照(这次它仅适用于卷,请确保此时 fs 一致),启动数据库,将快照备份为块设备。这可能会增加备份的大小,并且可能并非在所有配置上都可行。

  5. 备份实时数据库文件,并希望它在恢复时能够正常工作。(你这是在玩火。)如果可能的话,远离这个

  6. 如果您的技术有特殊的备份方式,请使用这种方式。(例如从 ELB 到 S3 的直接快照备份。)

无论你选择哪种方式,请记住你绝对应该测试您是否能够从备份中恢复多次,来自几个不同的备份。

#!/bin/bash
BACKUP_BASE="/data/backups/"
DIRNAME="mongo"
BUCKET="mybackups"
ARCHIVE_DIR="/data/backups_duplicity_archives/${DIRNAME}"
VERBOSE="-v 4"
S3_PARAMS="--s3-use-new-style" # --s3-use-multiprocessing" # --s3-use-rrs"
export PASSPHRASE="something"
export AWS_ACCESS_KEY_ID="AN_ID"
export AWS_SECRET_ACCESS_KEY="A_KEY"

cd ${BACKUP_BASE}
rm -rf ${BACKUP_BASE}/${DIRNAME}
/usr/bin/mongodump -h 10.0.0.1 -o ${BACKUP_BASE}/${DIRNAME}/databasename --oplog

/usr/bin/duplicity $S3_PARAMS --asynchronous-upload ${VERBOSE} --archive-dir=${ARCHIVE_DIR} incr --full-if-older-than 14D ${BACKUP_BASE}/${DIRNAME} "s3+http://${BUCKET}/${DIRNAME}"
if [ ! $! ]; then
        /usr/bin/duplicity $S3_PARAMS ${VERBOSE} --archive-dir=${ARCHIVE_DIR} remove-all-but-n-full 12 --force "s3+http://${BUCKET}/${DIRNAME}"
        /usr/bin/duplicity $S3_PARAMS ${VERBOSE} --archive-dir=${ARCHIVE_DIR} remove-all-inc-of-but-n-full 4 --force "s3+http://${BUCKET}/${DIRNAME}"
fi

答案2

数据大小已达到该过程占用过多磁盘空间的程度,并且文件无法一次性上传到 S3。

将它们作为单独的文件上传。您可能没有进行某种花哨的重复数据删除,如果您将其更改为基于引用,将会很有帮助。

到目前为止,已经通过转储整个 MongoDB 数据库完成了备份

有增量备份工具(https://github.com/EqualExperts/Tayra) 用于 MongoDB。如果您的更新负载相对较低,我会考虑使用这些。


由于您使用的是 Digital Ocean,因此无法进行本地备份。不过,这是需要从战略角度考虑的问题。如果您直接托管在 Amazon 上,那么将文件系统快照保存到 S3 可能会对您有所帮助。

相关内容