LIFULL Creators Blog

「株式会社LIFULL(ライフル)」の社員によるブログです。

AWS Database Migration Serviceを使ってみた話

こんにちは。テクノロジー本部の稲垣です。

LIFULLでは、提供するサービスによって、様々なDBが稼働しています。

異なるDBエンジン間でのデータ移行が必要となるプロジェクトが立ち上がることとなり、AWSが提供しているAWS Database Migration Service(AWS DMS)による検証を行う機会がありました。

www.lifull.blog

AWS Database Migration Service(AWS DMS)がリリースされて間もないころに、一度検証目的で使ったことがありましたが、今回使ってみて、色々と分かったことがあったので、紹介します。

AWS Database Migration Service(AWS DMS)とは

docs.aws.amazon.com

AWS Database Migration Service (AWS DMS)は、リレーショナル データベース、データ ウェアハウス、 NoSQL データベース、その他の種類のデータストアなど、さまざまなデータベースを格納できます。AWS DMS を使用して、オンプレミスのインスタンス間 (AWS クラウドセットアップを使用)、またはクラウドセットアップとオンプレミスセットアップの組み合わせの間で、AWS クラウドにデータを移行できます。

https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/Welcome.htmlより一部抜粋

Oracle,MySQL,PostgreSQL,MariaDB,Microsoft SQL Server,Db2,Amazon DynamoDB,Amazon S3など、様々なデータベースに対応しています。

また、RDS-RDS間でも利用することができます。

AWS Database Migration Service(以下 DMS)は、「レプリケーションインスタンス」を作成して、ソースおよびターゲットの「エンドポイント」を指定します。

そして、「データベース移行タスク」を作成して、移行処理を実行させるといった流れです。

f:id:LIFULL-inagaki:20210319202535p:plain
AWS DMSレプリケーションプロセス

https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/CHAP_GettingStarted.htmlより抜粋

上記の説明で出てきた、以下の3つについて説明します。

  • エンドポイント
  • データベース移行タスク
  • レプリケーションインスタンス
エンドポイント

データベースの接続情報の定義

ソースDB(Source Database)とターゲットDB(Target Database)それぞれに存在する

レプリケーションインスタンス(Replication Instance)

ソースDB、ターゲットDBとの接続を確立し、ソースDBで発生した変更内容をキャッシュする

データベース移行タスクが実行されるインスタンス

データベース移行タスク(Replication task)

ソースDBとターゲットDBの間でデータ移行を実際に行う場所

移行タスクのタイプが「フルロードのみ」、「フルロード+継続的なレプリケーション(CDC)」、「継続的なレプリケーション(CDC)のみ」によって、タスクの動作が異なります。

  • フルロードのみ:ソースDBから既存のデータをフルロードし、レプリケーションインスタンスにキャッシュし、ターゲットDBに適用

  • フルロード+継続的なレプリケーション(CDC):フルロードが終わった後に、ソースDBで変更があった内容を定期的に読み込み、レプリケーションインスタンスにキャッシュし、変更データをターゲットDBに反映させる

  • 継続的なレプリケーション(CDC)のみ:フルロードは行わずに、ソースDBで変更があった内容を定期的に読み込み、レプリケーションインスタンスにキャッシュし、変更データをターゲットDBに反映させる

今回は、フルロードのみおよび、フルロード+継続的なレプリケーション(CDC)での検証を行いました。

DMSを使用した2つのデータ移行パターン

実際にDMSを使用して、データ移行を行う場合、以下の2つのデータ移行パターンを想定しました。

  1. 移行用の環境を別途作り、動作確認した上で移行
  2. サービス運用しながらデータ移行
移行用の環境を別途作り、動作確認した上で移行

【データ移行の流れ】

  • 既存の本番環境と並行して、新しいDBに読み書きするアプリケーションを開発
  • データ移行用のターゲットDBを作成
  • データ移行タスクを設定
  • データ移行タスクをフルロード実行(新しいDBにソースDBのデータが反映される)
  • 新しいDBを参照して、動作確認
  • アプリケーションを本番環境にリリースする際は、一時的にサービスを止める
  • データ移行タスクを停止し、フルロード実行
  • 新しいアプリケーションをリリース(以降は新しいDBに対して読み書き)

【メリット】

  • 事前に動作確認を行っているため、本番環境での不具合を事前に発見できる
  • テストをして問題があった場合も、環境を再構築すれば切り戻しできる

【デメリット】

  • 環境構築に時間がかかる
  • 同じ機能のソースプログラムを複数管理しなければならない
サービス運用しながらデータ移行

【データ移行の流れ】

  • データ移行用のターゲットDBを作成
  • データ移行タスクを設定
  • ソースDBの変更内容をターゲットDBへ定期的に反映
  • アプリケーションのDB参照先を段階的にソースDBからターゲットDBに変更
  • 移行テーブル対象が増える際は、データ移行タスクを一時的に止めて、テーブルマッピングに追加→データ移行タスクを再開

【メリット】

  • リリースを止めずにデータ移行ができる
  • 最小限の構成でデータ移行ができる

【デメリット】

  • データ移行後に問題が発生した場合の切り戻しが困難
  • 本番環境に影響が出てしまった場合、事業へのマイナスインパクトがある

安全性を重視するのであれば「移行用の環境を別途作り、動作確認した上で移行」、多少安全性を犠牲にしても、工数を優先するのであれば「サービス運用しながらデータ移行」といった選択になります。


今回は、移行ケースとして、「サービス運用しながらデータ移行」を想定し、Data Migration Serviceの設定を行いました。

DMSの設定については、web上で紹介しているページがありますが、実際にやってみると、分かりにくい箇所がいくつかあったため、紹介します。



継続的なレプリケーション(CDC)を使用する際の注意点

ソースDB側の更新量に合わせた、レプリケーションインスタンスのサイジング

今回の移行ケースでは、ソースDBに更新が発生する状態で、ターゲットDBにデータ移行を行います。

よって、フルロード+継続的なレプリケーション(CDC)を採用するため、以下の流れでデータを反映していきます。

ソースDBで変更が発生

レプリケーションインスタンスで変更内容をキャッシュ

ターゲットDBに反映するためのSQLを生成

ターゲットDBに対して生成したSQLを実行し、変更を反映

ソースDBでのトランザクション処理順に、ターゲットDBに反映するための内容をレプリケーションインスタンス内でまとめて、ターゲットDBへ反映する処理を繰り返しています。

つまり、ソースDB側の更新量が多くなると、その分レプリケーションインスタンス内での処理にかかる負荷が増えていき、レプリケーション遅延を引き起こしやすくなります。


データベース移行タスクの設定について

データベース移行タスクについて、少し前で触れました。

データベース移行タスクを設定する際は、主に以下の2つです。

  • タスク設定
  • テーブルマッピング

タスク設定、テーブルマッピングともに、AWSコンソール上で直接設定する方法と、json形式で設定する方法があります。

テーブルマッピングについては、テーブル数が多いケースでは、json形式で設定したほうが楽です。

タスク設定については、検証時に設定した内容について触れます。

テーブル作成モードと再開・再起動

タスクを設定して、テーブルマッピングで設定したテーブルに対して、どういったモードで再開するかを設定できます。

テーブルマッピングの変更などで、定期的にタスクを停止および再開する際に使用します。

テーブル作成モードには、以下の3つがあります。

  • 何もしない:タスクを停止したときの状態のまま
  • ターゲット上のテーブルを削除:ターゲットDBのテーブル自体を削除
  • TRUNCATE:ターゲットDBのテーブルは残したままで、テーブルのデータのみ削除

そして、タスクを再開すると、新規にテーブルマッピングが追加されたテーブルについて、

テーブル作成モードが適用されます。

一時的にテーブルマッピングから外したテーブルを、再度追加した際に、テーブル作成モードを「何もしない」以外にしてしまうと、ターゲットDB側の該当テーブルのデータが消えてしまうので、注意が必要です。


CDCのTransactional Apply ModeとBatch Apply Mode

DMSタスクはデフォルトでは、Transactional Apply Modeです。 ソースDBでトランザクションがコミットされた順にターゲットDBへ適用されます。

一方で、ターゲットDBへの書き込み量を減らしたり、まとめて書くことで効率的に動作させることで、高パフォーマンスが期待できるBatch Apply Modeが存在します。

タスク設定のBatchApplyEnabledをTrueに設定することで、有効化できます。

Batch Apply Modeの場合、以下のようにまとめて変更を行うため、ソースDBでトランザクションがコミットされた順で、必ずしも反映されない可能性があります。

一定期間にソースDBに行われた変更をレプリケーションインスタンス上にキャッシュ

同一テーブルに対する複数のクエリはDMS側でまとめられる

最終的な変更をまとめてターゲットへ書き込む

今回の要件では、「サービス運用しながらデータ移行」することが前提であり、ソースDB内のテーブル間で依存関係があるテーブルが複数存在していたため、Batch Apply Modeの適用は見送りました。


DMSの検証

タスク設定に「検証の有効化」というチェックボックスがあります。

f:id:LIFULL-inagaki:20210325205542j:plain
「検証の有効化」チェックボックス

チェックボックスの下の説明には、以下のように書かれています。

全データのロードを実行した後すぐにAWS DMSでソースとターゲットのデータを比較する場合は、この設定を選択します。 検証することで、データが正確に移行されたことを確認できますが、完了するまでに通常より時間がかかります。

ソースDBとターゲットDBで、同じDBエンジンでデータベースの文字コードが異なる場合、DBエンジンが異なる場合など、ソースDB側に特殊文字などが入っていることが原因で、ターゲットDBに移行できないデータが存在するケースがあります。

その場合、ソースDBとターゲットDBで差分が生じてしまうのですが、DMSの検証を有効化することで、AWSコンソール上で差分が発生しているテーブルと原因となっているデータなどを検出してくれます。

データ移行で漏れが発生してしまうと、大きな問題になる可能性もあるので、データを確実に移行したいケースでは有効化するのがオススメです。

テーブルマッピングに設定したテーブル全てが、DMSの検証対象です。

しかし、以下の点に該当する場合は、有効な検証結果が得られない、大幅なレプリケーション遅延が発生するなど、サービスに影響が出てしまう可能性があります。

  • ソースDB側で大量の更新が定期的に発生するテーブルが存在する
  • ソースDB側に膨大なレコード数、およびカラム長が長いなど、データ量が多いテーブルが存在する

DMSの検証処理自体は、レプリケーションインスタンスで行われますが、ソースDBの変更をターゲットDBに反映するレプリケーション処理も、同じくレプリケーションインスタンスで行われています。

よって、DMSの検証処理、レプリケーション処理どちらかの負荷が大きくなると、もう片方の処理にも影響を与えてしまう可能性があります。

例えば、「サービス運用しながらデータ移行」するケースで、ターゲットDB側も既にアプリケーションで利用されている場合は、DMSの検証を有効化することで、レプリケーション処理自体が遅延してしまうというリスクを抱えてしまうことになるので、設定にあたっては検討が必要です。


DMSのログ

DMSのログとしては、以下があります。

  • DMSタスクログ

ClouwdWatch Logsに出力される

  • DMSタスク例外情報

ターゲットDB内にテーブルawsdms_apply_exceptionsが作成され、エラーが発生したテーブルやエラー情報が格納される

  • DMSの検証情報に関するログ

ターゲットDB内にテーブルawsdms_validation_failures_v1が作成され、エラーが発生したテーブルやエラー情報が格納される

awsdms_apply_exceptionsについては、カラムSTATEMENTに、ターゲット側でエラーが発生したときに実行されたステートメントが記録されます。

awsdms_validation_failures_v1については、カラムDETAILSに、DMS検証時に指定されたキーと一致しないすべてのソース/ターゲット列値のJSON形式の文字列(エラーとなったデータ)が記録されます。



実際に使用する前に確認しておくこと

色々と説明しましたが、DMSを本番稼働しているサービスに使用する場合、以下の点について、確認しておいたほうがよさそうです。

  • データ移行パターン(サービス運用しながら・移行用の環境を別途作る・開発を一定期間止める)
  • サービス運用しながらデータ移行する場合は、データ移行するソースDBで更新頻度が高いものがないか
  • 移行するテーブル間で依存関係があるものがあるか(依存関係がない場合は、Batch Apply Modeモードの適用も検討)
  • DMSタスクの数(複数稼働させる場合は、対応するレプリケーションインスタンスも用意するか)
  • DMSの検証有効化有無(DMSの検証を無効化する場合は、ソースDBとターゲットDBの差分チェック方法の検討)



おわりに

実際にData Migration Service(DMS)を使ってみて、分かりにくかった点について紹介しました。

オンプレミスで動いているDBをAWSへの移行を検討している、もしくはAWS内で別のDBエンジンへの移行などで、Data Migration Service(DMS)の利用を検討している方にとって、少しでもこの記事がお役に立てたら幸いです。