Linux

將完整數據備份到 Amazon S3

  • July 5, 2015

我有一個託管在 Digital Ocean 上的 Ubuntu 伺服器,它已經超出了現有的備份解決方案。

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

到目前為止,已通過轉儲整個 MongoDB 數據庫、保存 ES 配置以及複製應用程序目錄中的所有其他文件(日誌、程式碼本身等)來完成備份。如果是當月的第一天,所有使用者文件也會被複製,否則只會添加自當月第一天以來更改的文件。然後將所有這些壓縮到一個文件中並上傳到 Amazon S3。

數據大小已經到了這個過程佔用太多磁碟空間,文件無法一次性上傳到S3的地步。

這種大小的應用程序的下一個級別是什麼(8 GB 的使用者文件,125,000 個使用者,3,000 個其他文件,都可以在 ES 中搜尋)?

我了解基於意見的問題不適用於伺服器故障。我不是在徵求意見,只是針對這種規模的應用程序來說,正常的、具有成本效益的解決方案是什麼。

**更新:**這些是我嘗試使用 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 ---

我有使用duplicity備份的良好經驗。如果您能夠創建快照並將其以只讀方式掛載,那麼進行一致的增量備份是一個非常好的選擇。

通常問題出在備份數據庫(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

引用自:https://serverfault.com/questions/703407