DigitalOcean SpacesへのスケジュールされたMongoDBバックアップのセットアップ方法

前書き

定期的なデータベースバックアップは、意図しないデータ損失イベントから保護するための重要なステップです。 一般に、バックアップには大きく2つのカテゴリがあります。ファイルシステムレベル(「物理」)バックアップと論理バックアップです。

ファイルシステムレベルのバックアップでは、基礎となるデータファイルのある時点でのスナップショットを作成し、スナップショットファイルにキャプチャされた状態を使用してデータベースをきれいに回復できるようにします。 これらは、特にLVM snapshotsなどのファイルシステムスナップショット、またはDigitalOcean Block Storage Snapshotsなどのブロックストレージボリュームスナップショットと組み合わせて使用​​する場合に、大規模なデータベースを迅速にバックアップするのに役立ちます。

論理バックアップには、ツールの使用が含まれます(例: mongodumpまたはpg_dump)を使用して、データベースからバックアップファイルにデータをエクスポートします。バックアップファイルは、対応する復元ツール(例: mongorestoreまたはpg_restore)。 多くの場合、バックアップおよび復元するデータをきめ細かく制御し、データベースのバージョンやインストール間でバックアップを移植できます。 論理バックアップツールは、メモリを介してバックアップされるすべてのデータを読み取るため、処理速度が遅くなり、特に大規模なデータベースの場合に重要な負荷が大きくなる可能性があります。

効果的なバックアップおよびリカバリ戦略の設計には、多くの場合、パフォーマンスへの影響、実装コスト、およびデータストレージコストとリカバリ速度、データ整合性、およびバックアップカバレッジのトレードオフが伴います。 最適なソリューションは、リカバリポイントと時間objectives、およびデータベースの規模とアーキテクチャによって異なります。

このガイドでは、組み込みの論理バックアップツールであるmongodumpを使用してMongoDBデータベースをバックアップする方法を示します。 次に、結果のシリアル化されたデータバックアップファイルを圧縮して、冗長性の高いオブジェクトストアであるDigitalOcean Spacesにアップロードする方法を示します。 また、Bashとcronを使用してバックアップとアップロードの操作を定期的にスケジュールする方法を示し、最後にサンプルのデータ復旧シナリオで締めくくります。

このチュートリアルの終わりまでに、拡張可能な自動バックアップ戦略のフレームワークを実装して、アプリケーションがデータ損失に陥った場合に迅速に復旧できるようにします。 小規模から中規模のデータベースの場合、mongodumpを使用した論理バックアップにより、バックアップおよびリカバリするデータをきめ細かく制御できます。 これらの圧縮されたバックアップアーカイブをDigitalOcean Spacesに保存すると、耐久性のあるオブジェクトストアで容易に利用できるため、アプリケーションデータが保護され、データ損失イベントが発生した場合に迅速に回復できます。

[.note]#Note:mongodumpツールを使用すると、特に負荷の高いデータベースでパフォーマンスに影響が出る可能性があります。 最初に、負荷をシミュレートした非本番データベースを使用してこの手順をテストし、このメソッドが本番デプロイメントで機能することを確認する必要があります。

前提条件

このガイドを開始する前に、次の前提条件が利用可能であることを確認してください。

Dropletにログインし、MongoDBを起動して実行し、スペースを作成したら、すぐに使用を開始できます。

[[step-1 -—- insert-test-data]] ==ステップ1—テストデータを挿入します

クリーンなMongoDBインストールから開始し、まだデータを保存していない場合は、テスト目的で、最初にいくつかのサンプルデータをダミーのrestaurantsコレクションに挿入する必要があります。 データベースにすでにいくつかのコレクションとドキュメントが保存されている場合は、この手順をスキップして、Step 2に進んでください。

まず、MongoDBシェルを使用して実行中のデータベースに接続します。

mongo

次のMongoシェルプロンプトが表示されます。

MongoDB shell version: 3.2.19
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
    http://docs.mongodb.org/
Questions? Try the support group
    http://groups.google.com/group/mongodb-user
Server has startup warnings:
2018-04-11T20:30:57.320+0000 I CONTROL  [initandlisten]
2018-04-11T20:30:57.320+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2018-04-11T20:30:57.320+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2018-04-11T20:30:57.320+0000 I CONTROL  [initandlisten]
>

デフォルトでは、シェルはtestデータベースに接続します。

testデータベースに存在するコレクションを一覧表示しましょう。

show collections

データベースにはまだ何も挿入していないため、コレクションはなく、出力なしでプロンプトに戻ります。

ダミーのrestaurantsコレクションにドキュメントを挿入してみましょう。このコレクションは自動的に作成されます(まだ存在していないため)。

db.restaurants.insert({'name': 'Pizzeria Sammy'})

次の出力が表示されます。

OutputWriteResult({ "nInserted" : 1 })

これは、挿入操作が成功したことを示します。

コレクションをもう一度リストします。

show collections

新しく作成されたrestaurantsコレクションが表示されます。

Outputrestaurants

MongoDBシェルを終了するには、CTRL +Dを押します。

データベースにサンプルデータを保存したので、バックアップする準備が整いました。

[[step-2 -—- use-mongodump-to-back-up-mongodb-data]] ==ステップ2 —mongodumpを使用してMongoDBデータをバックアップします

次に、組み込みのmongodumpユーティリティを使用して、MongoDBデータベース全体を圧縮アーカイブファイルにバックアップ(または「ダンプ」)します。

まず、mongodumpによって作成されたアーカイブを保存するために、backupという一時ディレクトリを作成しましょう。

mkdir backup

それでは、このMongoDBインスタンスのtestデータベースをtest_dump.gzという圧縮アーカイブファイルにバックアップしましょう。 インスタンスに他のデータベースが含まれている場合は、--dbフラグの後にtestを別のデータベース名に置き換えることができます。 --dbフラグを省略して、MongoDBインスタンスのallデータベースをバックアップすることもできます。

[.note]#Note:次のコマンドはターミナルから実行する必要があり、notはMongoシェルです。

mongodump --db test --archive=./backup/test_dump.gz --gzip

ここでは、--archiveフラグを使用して、すべてのデータを単一のアーカイブファイル(場所はarchiveパラメーターで指定)に保存することを指定し、--gzipこのファイルを圧縮することを指定するフラグ。 さらに、オプションで、--collectionまたは--queryフラグを使用して、アーカイブする特定のコレクションまたはクエリを選択できます。 これらのフラグの詳細については、mongodumpdocumentationを参照してください。

dumpコマンドを実行すると、次の出力が表示されます。

Output2018-04-13T16:29:32.191+0000    writing test.restaurants to archive './backup/test_dump.gz'
2018-04-13T16:29:32.192+0000    done dumping test.restaurants (1 document)

これは、テストデータが正常にダンプされたことを示しています。

次のステップでは、このバックアップアーカイブをオブジェクトストレージにアップロードします。

[[step-3 -—- upload-the-backup-archive-to-digitalocean-spaces]] ==ステップ3—バックアップアーカイブをDigitalOceanSpacesにアップロードします

このアーカイブをDigitalOceanSpaceにアップロードするには、Prerequisitesにインストールして構成したs3cmdツールを使用する必要があります。

最初にs3cmd構成をテストし、バックアップスペースへのアクセスを試みます。 このチュートリアルでは、スペース名としてmongo-backup-demoを使用しますが、スペースの実際の名前を入力する必要があります。

s3cmd info s3://mongo-backup-demo/

次の出力が表示されます。

Outputs3://mongo-backup-demo/ (bucket):
   Location:  nyc3
   Payer:     BucketOwner
   Expiration Rule: none
   Policy:    none
   CORS:      none
   ACL:       3587522: FULL_CONTROL

これは、接続が成功し、s3cmdがオブジェクトをスペースに転送できることを示しています。

手順2で作成したアーカイブをputコマンドを使用してSpaceに転送しましょう。

s3cmd put ./backup/test_dump.gz s3://mongo-backup-demo/

ファイル転送の出力が表示されます。

Outputupload: './backup/test_dump.gz' -> 's3://mongo-backup-demo/test_dump.gz'  [1 of 1]
 297 of 297   100% in    0s    25.28 kB/s  done

転送が完了すると、スペースのコンテンツを一覧表示して、ファイルがスペースに正常に転送されたことを確認します。

s3cmd ls s3://mongo-backup-demo/

バックアップアーカイブファイルが表示されます。

Output2018-04-13 20:39       297   s3://mongo-backup-demo/test_dump.gz

この時点で、test MongoDBデータベースのバックアップに成功し、バックアップアーカイブをDigitalOceanSpaceに転送しました。

次のセクションでは、cronを使用してスケジュールできるように、Bashを使用して上記の手順をスクリプト化する方法について説明します。

[[step-4 -—- create-and-test-backup-script]] ==ステップ4—バックアップスクリプトの作成とテスト

MongoDBデータベースを圧縮アーカイブファイルにバックアップし、このファイルをSpaceに転送したので、これらの手動手順を1つのBashスクリプトに結合できます。

バックアップスクリプトを作成

まず、mongodumpコマンドとs3cmd putコマンドを組み合わせたスクリプトを作成し、いくつかのロギング( `echo`sを使用)のように、いくつかの追加のベルとホイッスルを追加します。

好みのテキストエディタで空のファイルを開きます(ここではnanoを使用します)。

nano backup_mongo.sh

次のコードスニペットを貼り付け、関連する値を更新して、独自のスペース、データベース、およびファイル名を参照するようにしてください。 ファイルをbackup_mongo.shと呼びますが、このファイルには任意の名前を付けることができます。 このセクションの最後で完全なスクリプトを見つけることもできます。

このスクリプトを1つずつ見ていきましょう。

backup_mongo.sh

#!/bin/bash

set -e
...

ここで、#!/bin/bashは、スクリプトをBashコードとして解釈するようにシェルに指示します。 set -eは、スクリプトコマンドのいずれかが失敗した場合、インタプリタにすぐに終了するように指示します。

backup_mongo.sh

...

SPACE_NAME=mongo-backup-demo
BACKUP_NAME=$(date +%y%m%d_%H%M%S).gz
DB=test

...

このセクションでは、後で使用する3つの変数を設定します。

  • SPACE_NAME:バックアップファイルをアップロードするDigitalOceanスペースの名前

  • BACKUP_NAME:バックアップアーカイブの名前。 ここでは、基本的な日時文字列に設定します。

  • DB:スクリプトがバックアップするMongoDBデータベースを指定します。 MongoDBインスタンス全体(すべてのデータベース)をバックアップする場合、この変数は使用されません。

backup_mongo.sh

...

date
echo "Backing up MongoDB database to DigitalOcean Space: $SPACE_NAME"

echo "Dumping MongoDB $DB database to compressed archive"
mongodump --db $DB --archive=$HOME/backup/tmp_dump.gz --gzip

echo "Copying compressed archive to DigitalOcean Space: $SPACE_NAME"
s3cmd put $HOME/backup/tmp_dump.gz s3://$SPACE_NAME/$BACKUP_NAME

...

次に、(ログ記録の目的で)日付と時刻を出力し、上記でテストしたmongodumpコマンドを実行してバックアップを開始します。 もう一度、バックアップアーカイブを~/backup/に保存します。

次に、s3cmdを使用して、このアーカイブをこれら2つのSPACE_NAME変数とBACKUP_NAME変数で指定された場所にコピーします。 たとえば、スペース名がmongo-backup-demoで、現在の日時が2018/04/12 12:42:21の場合、バックアップには180412_124221.gzという名前が付けられ、mongo-backup-demoスペースに保存されます。 。

backup_mongo.sh

...

echo "Cleaning up compressed archive"
rm $HOME/backup/tmp_dump.gz

echo 'Backup complete!'

ここでは、バックアップアーカイブをスペースに正常にコピーしたので、~/backupディレクトリから削除します。最終出力は、バックアップが完了したことを示します。

これらすべてのコードスニペットを組み合わせた後、完全なスクリプトは次のようになります。

backup_mongo.sh

#!/bin/bash

set -e

SPACE_NAME=mongo-backup-demo
BACKUP_NAME=$(date +%y%m%d_%H%M%S).gz
DB=test

date
echo "Backing up MongoDB database to DigitalOcean Space: $SPACE_NAME"

echo "Dumping MongoDB $DB database to compressed archive"
mongodump --db $DB --archive=$HOME/backup/tmp_dump.gz --gzip

echo "Copying compressed archive to DigitalOcean Space: $SPACE_NAME"
s3cmd put $HOME/backup/tmp_dump.gz s3://$SPACE_NAME/$BACKUP_NAME

echo "Cleaning up compressed archive"
rm $HOME/backup/tmp_dump.gz

echo 'Backup complete!'

完了したら、このファイルを必ず保存してください。

次に、このスクリプトをテストして、すべてのサブコマンドが機能することを検証します。

バックアップスクリプトのテスト

backup_mongo.shスクリプトをすばやく実行してみましょう。

まず、スクリプトを実行可能にします。

chmod +x backup_mongo.sh

次に、スクリプトを実行します。

./backup_mongo.sh

次の出力が表示されます。

OutputMon Apr 16 22:20:26 UTC 2018
Backing up MongoDB database to DigitalOcean Space: mongo-backup-demo
Dumping MongoDB test database to compressed archive
2018-04-16T22:20:26.664+0000    writing test.restaurants to archive '/home/sammy/backup/tmp_dump.gz'
2018-04-16T22:20:26.671+0000    done dumping test.restaurants (1 document)
Copying compressed archive to DigitalOcean Space: mongo-backup-demo
upload: '/home/sammy/backup/tmp_dump.gz' -> 's3://mongo-backup-demo/180416_222026.gz'  [1 of 1]
 297 of 297   100% in    0s     3.47 kB/s  done
Cleaning up compressed archive
Backup complete!

バックアップシェルスクリプトが正常に作成され、cronを使用してスケジュールを設定できるようになりました。

[[step-5 -—- schedule-daily-backups-using-cron]] ==ステップ5—Cronを使用して毎日のバックアップをスケジュールする

バックアップスクリプトの夜間実行をスケジュールするには、Unixライクなオペレーティングシステムに組み込まれているジョブスケジューリングユーティリティであるcronを使用します。

最初に、バックアップスクリプトのログを保存するディレクトリを作成します。 次に、バックアップスクリプトをcrontab(cronの構成ファイル)に追加して、cronが毎晩実行するようにスケジュールします。 cronは任意の定期的な頻度をサポートしているため、オプションで毎週または毎月のバックアップをスケジュールできます。

ロギングディレクトリを作成する

バックアップスクリプトのログファイルを保存するディレクトリを作成しましょう。 これらのログにより、バックアップスクリプトを定期的にチェックしてすべてが正常であることを確認し、一部のコマンドが失敗した場合にデバッグできます。

/var/logmongo_backupサブディレクトリを作成します(慣例により、ロギングに使用されます)。

sudo mkdir /var/log/mongo_backup

ここで、そのディレクトリをUnixユーザーに書き込み可能にします。 この場合、ユーザーの名前はsammyですが、サーバーのsudo権限を持つ関連するroot以外のユーザー名を使用する必要があります。

sudo chown sammy:sammy /var/log/mongo_backup

Unixユーザーsammy/var/log/mongo_backupに書き込むことができるようになりました。 cronジョブはsammyとして実行されるため、ログファイルをこのディレクトリに書き込むことができます。

スケジュールされたcronjobを作成しましょう。

Cronjobを作成

cronジョブを作成するには、「crontab」と呼ばれる、スケジュールされたジョブのリストを含むファイルを編集します。複数のcrontabがあり、ユーザーごとに1つあり、/etc/crontabにシステム全体のcrontabがあることに注意してください。 このチュートリアルでは、ユーザーsammyとしてバックアップスクリプトを実行します。ユースケースに応じて、システム全体のcrontabから実行することを選択できます。

編集のためにcrontabを開きます。

crontab -e

次のメニューが表示され、好みのテキストエディターを選択できます。

Outputno crontab for sammy - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/ed
  2. /bin/nano        <---- easiest
  3. /usr/bin/vim.basic
  4. /usr/bin/vim.tiny

Choose 1-4 [2]: no crontab for sammy - using an empty one

ご希望のエディターを選択してください。 nanoを選択するには、2と入力します。 次に、コメントアウトされたセクションの後に、ファイルに次の行を追加します。

クロンタブ-e

# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

0 2 * * * /home/sammy/mongo_backup.sh >>/var/log/mongo_backup/mongo_backup.log 2>&1

crontabの最後に必ず末尾の改行を含めるようにしてください。 ファイルを保存して閉じます。

次の出力が表示されます。

Outputno crontab for sammy - using an empty one
crontab: installing new crontab

これで、バックアップスクリプトは毎朝午前2時に実行されます。 stdoutstderr(出力ストリームとエラーストリーム)の両方がパイプ処理され、前に作成したログディレクトリのmongo_backup.logというログファイルに追加されます。

0 2 * * *(cron構文では毎晩午前2:00に実行)を希望のバックアップ頻度と時間に変更できます。 cronとその構文の詳細については、How To Use Cron To Automate Tasks On A VPSに関するチュートリアルを参照してください。

バックアップが機能することを確認するために、このチュートリアルをクイックリカバリ演習で締めくくります。

[[step-6 -—- perform-a-test-recovery]] ==ステップ6—テストリカバリを実行します

バックアップ戦略には、定期的にテストされる回復手順を含める必要があります。 ここでは、DigitalOceanスペースにアップロードした圧縮バックアップファイルからの復元を簡単にテストします。

まず、スペースからMongoDBドロップレットのホームディレクトリにtest_dump.gzをダウンロードします。

s3cmd get s3://mongo-backup-demo/test_dump.gz

次の出力が表示されます。

Outputdownload: 's3://mongo-backup-demo/test_dump.gz' -> './test_dump.gz'  [1 of 1]
 297 of 297   100% in    0s  1305.79 B/s  done

このチュートリアルを新しいMongoDBインスタンスで開始した場合、バックアップしたデータベースはtestデータベースのみであったことを思い出してください。

デモンストレーションのために、このテストデータベースを削除して、クリーンリストアを実行できるようにします。 この最初の手順を実行しない場合、復元手順では元のドキュメントが検出されるため、スキップされます。 特定のユースケースでは、新しいドキュメントのみの復元が許容される場合がありますが、このチュートリアルの目的のために、空のデータベースへの完全な復元を明示的にテストしたいと思います。

mongoシェルを使用してMongoDBインスタンスに接続します。

mongo

ここで、usetestデータベースであり、MongoDBインスタンスから削除します。

use test
db.dropDatabase()

testのドロップを確認する次の出力が表示されます。

Output{ "dropped" : "test", "ok" : 1 }

ここで、mongoシェルを終了し、mongorestoreコマンドを実行します。

mongorestore --gzip --archive=test_dump.gz --db test

ここでは、ソースバックアップファイルが圧縮され、「アーカイブファイル」形式であることを指定し(mongodumpを呼び出すときに--archiveフラグと--gzipフラグを使用したことを思い出してください)、 testデータベースに復元したい。

次の出力が表示されます。

Output2018-04-16T23:10:07.317+0000    creating intents for archive
2018-04-16T23:10:07.453+0000    reading metadata for test.restaurants from archive 'test_dump.gz'
2018-04-16T23:10:07.497+0000    restoring test.restaurants from archive 'test_dump.gz'
2018-04-16T23:10:07.541+0000    restoring indexes for collection test.restaurants from metadata
2018-04-16T23:10:07.541+0000    finished restoring test.restaurants (1 document)
2018-04-16T23:10:07.541+0000    done

これは、testの復元が成功したことを示しています。

結論として、最初のrestaurantsデータが正常に復元されたことを確認しましょう。

MongoDBシェルを開き、restaurantsコレクションをクエリします。

db.restaurants.find()

このチュートリアルの最初のステップで保存したオブジェクトが表示されます。

Output{ "_id" : ObjectId("5ace7614dbdf8137afe60025"), "name" : "Pizzeria Sammy" }

これで、このMongoDBバックアップ戦略の実装とテストが正常に完了しました。

結論

このチュートリアルでは、夜間の論理的なMongoDBバックアップの戦略を実装およびテストする方法を学びました。

このガイドは、さまざまな方法で拡張または変更できます。 いくつかの簡単な提案を次に示します。

  • リカバリポイントの目標(RPO)に応じて、データリカバリウィンドウに合わせて、推奨されるバックアップ頻度を増減することができます。

  • 別の便利な追加機能は、バックアップスクリプトサブコマンドが失敗した場合にトリガーされるアラート機能です(例: この機能は、定期的に監視されるアラート受信ボックスにメールを送信できます)。

  • このスクリプトは、スペースオブジェクトの削除を処理しません。 たとえば、6か月ほど前のバックアップを一掃することもできます。

  • 本番ユースケースによっては、より複雑なbackup rotation schemeを実装することもできます。

mongodumpプロシージャでは、ダンプされたすべてのデータをすばやく読み取る必要があるため、このバックアップ方法は、中小規模のデータベース、特に特定のコレクションや結果セットなどの部分的なバックアップに最適です。 大規模な展開には、ファイルシステムレベルのバックアップをお勧めします。 ファイルシステムレベルのMongoDBバックアップの詳細については、How To Back Up MongoDB Using Droplet Snapshotsに関するこのチュートリアルを参照してください。 MongoDBデータベースをバックアップするさまざまな方法の詳細については、MongoDB manualを参照してください。

このチュートリアルで紹介するソリューションは、mongodumpを活用してバックアップデータのカバレッジをきめ細かく制御し、DigitalOceanSpacesを活用して費用効果が高く耐久性のある長期データストレージを実現します。 mongodumpバックアップユーティリティの詳細については、MongoDBマニュアルのreference pageを参照してください。 DigitalOcean Spacesの詳細については、An Introduction To DigitalOcean Spacesを参照してください。

Related