MongoDB Atlasへのデータ移行 〜Live Migration〜 について #MongoDB #MongoDBAtlas
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
MongoDB Atlasへのデータ移行 〜Live Migration〜 について
Live Migrationをやってみた
GCP上にMongoDBのレプリカセットの構築
サンプルデータの挿入
MongoDB Atlasにクラスタを作成
ライブマイグレーションの実行
MongoDB Atlasへのデータ移行 〜Live Migration〜 について
- 本記事では、MongoDB AtlasのLive Migration機能を紹介致します。
- Live Migrationではクライアントからのダウンタイムがほぼ存在しない状態でAtlas環境への移行が出来ます。
- MongoDB Atlasとは
- クラウド環境上でのフルマネージドのMongoDBを軸としたサービスです。
- デプロイ先のクラウドプロバイダとしては、AWS, GCP, Azureを選択する事が可能です。
- Live Migrationに関するドキュメントはここにあります。
- 以下のような流れで行われます。
- Atlasで新しいClusterを作成
- 移行先となるMongoDB Clusterを Atlas上に構成します。
- データのライブマイグレート〜同期の完了
- ライブマイグレート中は既存のMongoDBへの読み書きが可能で、Atlasへの初期コピーが完了した後もデータの変更が監視されて同期処理が行われます。
- クライアントからの書き込みの停止〜接続先の変更〜カットオーバ
- クライアントからの書き込みを一時的に停止する必要があります。
- カットオーバする事でライブマイグレートは完了になりますので、クライアントからの接続先を移行後のMongoDB Atlas環境へ変更する事が出来ます。
- AWS, GCP, Azure, On-premiss環境でのセルフマネージド環境やサードパーティのDatabase as a Service プロバイダからのライブマイグレーションに対応しています。
- AWS, GCP, オンプレ環境からの移行方法の他に、 mLab, ObjectRocket, ComposeなどのサードパーティDBaaSからの移行方法のドキュメントが用意されています。
- 2021/3/1時点でAzureからの移行ドキュメントはありませんでした。
- Live Migration機能は無料で使用する事が出来ます。
- マイグレーションの移行元、移行先として無料枠のAtlas Clusterを選択することは出来ません。
- マイグレーションの移行元、移行先としてVPC peering又はプライベートエンドポイントはサポートされていません。
- 移行元のMongoDB versionは2.6以上である必要があります。
- 移行元のMongoDB側へのデータ抽出アクセスが発生するのでFireWallで許可する必要があります。
- 移行先のAtlas Cluster側で予めクライアントからのアクセスを許可しておく必要があります。
- 移行元のMongoDBはreplica set構成である必要があります。(Standaloneの場合は事前にReplicaset構成への変更が必要。)
- 移行元のMongoDBへの認証方式は、MongoDBのデフォルトの認証方式であるSCRAM(Salted Challenge Response Authentication Mechanism)である必要があります。
- ユーザとロールのデータは移行対象に含まれません。
Live Migrationをやってみた
- GCPのVM上に構成したMongoDBレプリカセットからMongoDB AtlasへのLive Migrationを試してみます。
- GCP上にMongoDBのレプリカセットの構築
- サンプルデータの挿入
- MongoDB Atlasにクラスタを作成
- ライブマイグレーションの実行
GCP上にMongoDBのレプリカセットの構築
- GCEでVMインスタンスを3台構築し、それぞれにMongoDBをインストール
- 構成
OS: CentOS7
MongoDB Enterprise 4.4
-
インストールメモ
- レポジトリ追加
$ sudo cat < /etc/yum.repos.d/mongodb-enterprise-4.4.repo [mongodb-enterprise-4.4] name=MongoDB Enterprise Repository baseurl=https://repo.mongodb.com/yum/redhat/7/mongodb-enterprise/ 4.4/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-4.4.asc EOF
- インストール
$ sudo yum install -y mongodb-enterprise-4.4.4 mongodb-enterprise-server-4.4.4 mongodb-enterprise-shell-4.4.4 mongodb-enterprise-mongos-4.4.4 mongodb-enterprise-tools-4.4.4
- config
$ sudo cat < /etc/mongod.conf systemLog: destination: file logAppend: true path: /var/log/mongodb/mongod.log storage: dbPath: /var/lib/mongo journal: enabled: true processManagement: fork: true pidFilePath: /var/run/mongodb/mongod.pid net: port: 27017 bindIp: 0.0.0.0 replication: oplogSizeMB: 2048 replSetName: "repl" EOF
- ulimit設定
$ sudo cat < /etc/systemd/system/mongod.service.d/override. conf [Service] # Other directives omitted # (file size) LimitFSIZE=infinity # (cpu time) LimitCPU=infinity # (virtual memory size) LimitAS=infinity # (locked-in-memory size) LimitMEMLOCK=infinity # (open files) LimitNOFILE=64000 # (processes/threads) LimitNPROC=64000 EOF
- デイレクトリ作成
$ sudo mkdir -p /var/lib/mongo $ sudo mkdir -p /var/log/mongodb $ sudo chown -R mongod:mongod /var/lib/mongo $ sudo chown -R mongod:mongod /var/log/mongodb
- SE Linux設定
$ sudo yum install checkpolicy $ sudo cat > mongodb_cgroup_memory.te < mongodb_proc_net.te < rs.initiate({ _id: "repl", members: [{_id: 0, host: "mongodb0:27017"}] }) repl:OTHER> repl:SECONDARY> repl:SECONDARY> repl:PRIMARY>
- レプリカセット セカンダリ追加
repl:PRIMARY> rs.add("mongodb1:27017") { "ok" : 1 } repl:PRIMARY> rs.add("mongodb2:27017") { "ok" : 1 }
- レプリカセット設定確認
repl:PRIMARY> rs.conf()
- マイグレーション用のユーザの作成(MongoDB3.4以降の場合の記載です。3.2以前の場合は設定が異なります。)
> use admin
> db.createUser(
{
user: "mySourceUser",
pwd: "mySourceP@$$word",
roles: [ "clusterMonitor", "readAnyDatabase" ]
}
)
Successfully added user: {
"user" : "mySourceUser",
"roles" : [
"clusterMonitor",
"readAnyDatabase"
]
}
サンプルデータの挿入
- データ移行を確認する為にサンプルのデータベース、コレクションを作成してデータを挿入しておきます。
> use migration_test
switched to db migration_test
> db.createCollection("source_collection")
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1614674363, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1614674363, 1)
}
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
migration_test 0.000GB
> db.source_collection.count()
0
> db.source_collection.insert({"document_number": 1})
WriteResult({ "nInserted" : 1 })
> db.source_collection.insert({"document_number": 2})
WriteResult({ "nInserted" : 1 })
> db.source_collection.insert({"document_number": 3})
WriteResult({ "nInserted" : 1 })
> db.source_collection.insert({"document_number": 4})
WriteResult({ "nInserted" : 1 })
> db.source_collection.insert({"document_number": 5})
WriteResult({ "nInserted" : 1 })
> db.source_collection.count()
5
MongoDB Atlasにクラスタを作成
- 移行先となるMongoDB Atlas Clusterを作成します。
- 以下の構成で作成しました。
Cloud Provider:GCP
Region:Tokyo(asia-northeast1)
Cluster Tier:M10(1.7GB RAM, 10GB Storage, 0.5 vCPUs)
Additional Settings:MongoDB 4.4, No Backup
Cluster Name:Cluster0
- クライアントアプリケーションから移行先のAtlas Clusterへの接続を許可する
- ローカルの端末上のmongoシェルから接続できるようにIP white listを追加して、DBユーザ、パスワードを設定しました。
- 接続確認
$ mongo "mongodb+srv://XXXXXX.mongodb.net/myFirstDatabase" --username dbuser
- マイグレーションが完了すると、移行先のAtlas Clusterではローリング再起動が行われる為、事前にフェイルオーバーのテストを実施する事が推奨されています。
ライブマイグレーションの実行
-
MongoDB Atlasの画面からLive Migrationを実行します。
- MongoDB Atlasへログインして移行先のClusterを表示します。
- 「Migrate Data to this CLuster」をクリックします。
- 「I'm ready to migrate」をクリックすると、いくつかの入力項目が求められます。
- 以下のIPから移行元DBへのアクセスを許可する必要がありますのでGCP側の設定でルールを設定します。
- 移行元のプライマリDBのアドレス:ポートを記載します。
- ユーザネームとパスワードを記載します。ここではマイグレーション用に作成したユーザ(mySourceUser)を使用しました。
- 移行元MongoDB側でSSLの設定を有効にしている場合にYESを選択します。
今回は有効にしておりませんのでそのままです。
有効にした場合はCAFileのアップロードが必要です。
- 移行前に移行先のAtlas Clusterのコレクションを全て削除する場合はYESを選択します。
ここではNOのままとしました。
- 「Validate」をクリックするとAtlasから移行元のDBへの接続確認が実施されます。
- 接続に問題がない事が確認されると、「Start Migration」を選択出来るようになるので、クリックします。
以下のプロセスが実行されます。- コレクションのコピー
- indexの作成
- oplogのコピーとtail
- Migration進行中の表示になります。
-
初期同期が完了すると以下のような表示になります。
遅延時間が示されますが、oplogのコピーが進行すると徐々に減少していきます。
遅延時間の表示と、「Prepare to Cutover」の表示がグリーンになると次のステップに進む事が出来ます。
また、このタイミングで72時間のカットオーバータイマーがセットされ、72時間をすぎるとAtlasは同期処理を停止します。
このタイマーは「Extend time」のリンクをクリックする事で24時間延長出来ます。
-
ここでデータの移行確認を行ってみます。
- まずは事前に作成したデータベースとコレクションの情報が同期されているかを確認します。
- 移行先のAtlas Clusterへ接続します。
$ mongo "mongodb+srv://XXXXX.mongodb.net/myFirstDatabase" --username dbuser
- 作成したデータベース"migration_test"が作成されています。
> show dbs admin 0.000GB config 0.000GB local 0.001GB migration_test 0.000GB
- 作成したコレクションが作成され、データが同期されています。
> use migration_test switched to db migration_test > db.source_collection.count() 5
- 次に移行元のDBへ新しい更新を加えた時に、変更が動的に反映されるかを確認します。
- 移行元のMongoDBへ接続します。
$ mongo
- コレクションに追加でデータを挿入します。
> show dbs admin 0.000GB config 0.000GB local 0.001GB migration_test 0.000GB > use migration_test switched to db migration_test > db.source_collection.count() 5 > db.source_collection.insert({"document_number": 6}) WriteResult({ "nInserted" : 1 }) > db.source_collection.insert({"document_number": 7}) WriteResult({ "nInserted" : 1 }) > db.source_collection.count() 7
- 移行先のAtlas Clusterへ接続します。
$ mongo "mongodb+srv://XXXXX.mongodb.net/myFirstDatabase" --username dbuser
- 移行先のAtlas Clusterへ同期されている事が分かります。
> show dbs admin 0.000GB config 0.000GB local 0.001GB migration_test 0.000GB > use migration_test switched to db migration_test > db.source_collection.count() 7
- カットオーバーを実施します。
- 「PREPARE TO CUTOVER」をクリックします。
- カットオーバーに必要なステップが表示されます。
- 移行元データベースへの書き込みを停止します。
- ギャップが解消され、完全に同期された事を確認します。
- 記載されている新しい接続先にクライアントアプリケーションの接続先を切り替えます。
- 「Cut over」をクリックして完了です。これで同期処理も終了します。
- 「Success! Your cluster migration is complete.」
以上になります。
尚、Production環境での実施については、ライブマイグレーションのステップを2回に分けて実行する事が推奨されています。
1. Staging環境のAtlasを用意してLive Migrationを実施。
2. カットオーバーをする前にアプリケーションを移行したStaging環境に接続して十分なテストを行う。
3. 問題なければProduction環境のAtlasでライブマイグレーションを実施。
Atlasへの移行はLive Migrationツールにより非常に簡単にダウンタイムをほぼゼロで実現出来そうです。
いかがでしたでしょうか?
クリエーションラインでは、MongoDB Atlasの導入支援サービス、日本円での請求書対応、日本語でのテクニカルサポートなどを提供しております。
ご興味ある方は、お問い合わせ下さい