このドキュメントでは、Terraform を使用して Dataflow と Datastream をデプロイし、ダウンタイムを最小限に抑えながら、ソース MySQL インスタンスから Spanner へのライブデータの移行を行う方法について説明します。
ライブデータの移行を実行し、すべてのデータが転送されたこと、コードと依存関係が移行され、テストが完了したことを確認したら、ソースの MySQL データベースではなく Spanner を使用するようにアプリケーションを切り替えることができます。
ライブデータの移行は、移行先の Spanner データベースを作成した後に実行できます。データを移行する前に、移行先データベースに互換性のあるスキーマを作成する必要があります。
仕組み
ライブデータ移行は、次の 2 つのフェーズで構成されます。
バックフィルの移行:
- バックフィルの移行を行う間、Dataflow はソース MySQL データベースから既存のデータを読み取り、ターゲット Spanner データベースに移行します。ソース MySQL インスタンスから Spanner にデータを移動するには、一括移行用の Dataflow テンプレートを使用する必要があります。
- バックフィルの移行で Spanner への行の書き込みに失敗すると、その行は Cloud Storage バケットのデッドレター キュー ディレクトリに書き込まれます。バックフィルの移行でこれらの行の Spanner への書き込みを再試行できます。
変更データ キャプチャ(CDC)の移行:
- このフェーズはバックフィルの移行と同時に行われ、ソース MySQL インスタンスで発生した変更をリアルタイムでキャプチャします。これらの変更は、バックフィルの移行の完了後に Spanner に適用されます。
- ソースの MySQL インスタンスで発生した変更を Datastream を使用してリアルタイムでキャプチャし、Cloud Storage バケットに書き込む必要があります。
- バックフィルの移行が完了したら、Dataflow を使用して CDC を Cloud Storage バケットから Spanner に移動します。なんらかの理由で Dataflow が Spanner に行を書き込めなかった場合、その行は別の Cloud Storage バケットのデッドレター キュー ディレクトリに書き込まれます。CDC の移行は、デッドレター キュー ディレクトリから Spanner への行の書き込みを自動的に再試行します。
稼働中データの移行を計画する
ソース MySQL インスタンス、Datastream、Dataflow、Cloud Storage バケット、ターゲット Spanner データベース間でデータが転送されるために必要なネットワーク インフラストラクチャを構成する必要があります。安全な移行のために、プライベート ネットワーク接続を構成することをおすすめします。組織のコンプライアンス要件によっては、パブリック ネットワークまたはプライベート ネットワークの接続の構成が必要になる場合があります。Datastream 接続の詳細については、ネットワーク接続オプションをご覧ください。
ライブデータの移行を計画するには、組織のネットワーク管理者が次のタスクを行う必要があります。
- デフォルトの VPC を使用する、またはプロジェクトに次の要件で新しい VPC を作成します。
- ソース MySQL インスタンスがこの VPC で利用可能である必要があります。この VPC に下り(外向き)ファイアウォール ルールを、ソース MySQL インスタンスが配置されている VPC に上り(内向き)ファイアウォール ルールを作成する必要がある場合があります。
- この VPC で Datastream、Dataflow、Cloud Storage バケット、ターゲット Spanner データベースを使用できる必要があります。
- VPC からの接続を許可するには、移行元の MySQL インスタンスに許可リストを作成する必要があります。
- Datastream が使用できる VPC 内の IP アドレス範囲を決定して割り振ります。
- Dataflow がバックフィルの移行を完結するために使用するサブネットワークを VPC に作成します。
- CDC の移行を完結させるために Dataflow が後で使用するサブネットを VPC に作成します。
ライブデータの移行は、次の手順で行うことができます。
ライブデータの移行を行うには、大量のリソースをデプロイして管理する必要があります。Spanner には、ライブデータの移行の各フェーズに 2 つのサンプル Terraform テンプレートが用意されています。
ライブ マイグレーションのテンプレートでは、CDC の移行が次の 2 つのフェーズで実行されます。
- Datastream を使用して、Cloud Storage バケットへの CDC の移行を設定します。Terraform 変数を使用して、テンプレートにより Dataflow ジョブが作成されないよう設定できます。
- Dataflow を使用して、Cloud Storage バケットから Spanner に CDC を移行します。このフェーズは、バックフィルの移行のための Terraform テンプレートを使用したバックフィルの後に実行する必要があります。
バックフィルの移行のための Terraform テンプレートは、ソース MySQL インスタンスから Spanner へのバックフィルの移行を実行します。
始める前に
- Terraform がローカルシェルにインストールされていることを確認します。
- ライブデータの移行を実行するサービス アカウントを作成します。サービス アカウントの作成の詳細については、サービス アカウントを作成するをご覧ください。
-
ライブ マイグレーションの実行に必要な権限がサービス アカウントに付与されるように、プロジェクトに対する次の IAM ロールをサービス アカウントに付与するよう管理者に依頼してください。
-
Dataflow 管理者(
roles/dataflow.admin) -
Datastream 管理者(
roles/datastream.admin) -
セキュリティ管理者(
roles/iam.securityAdmin) -
サービス アカウント管理者(
roles/serviceAccountAdmin) -
Pub/Sub 管理者(
roles/pubsub.admin) -
ストレージ管理者(
roles/storage.admin) -
Compute ネットワーク管理者(
roles/compute.networkAdmin) -
閲覧者(
roles/viewer)
ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。
これらの事前定義ロールには、ライブ マイグレーションの実行に必要な権限が含まれています。必要とされる正確な権限については、必要な権限セクションを開いてご確認ください。
必要な権限
ライブ マイグレーションを行うには、次の権限が必要です。
-
compute.globalAddresses.create -
compute.globalAddresses.createInternal -
compute.globalAddresses.createInternal -
compute.globalAddresses.delete -
compute.globalAddresses.deleteInternal -
compute.globalAddresses.get -
compute.globalOperations.get -
compute.networks.addPeering -
compute.networks.get -
compute.networks.listPeeringRoutes -
compute.networks.removePeering -
compute.networks.use -
compute.routes.get -
compute.routes.list -
compute.subnetworks.get -
compute.subnetworks.list -
dataflow.jobs.cancel -
dataflow.jobs.create -
dataflow.jobs.updateContents -
datastream.connectionProfiles.create -
datastream.connectionProfiles.delete -
datastream.privateConnections.create -
datastream.privateConnections.delete -
datastream.streams.create -
datastream.streams.delete -
datastream.streams.update -
iam.roles.get -
iam.serviceAccounts.actAs -
pubsub.subscriptions.create -
pubsub.subscriptions.delete -
pubsub.topics.attachSubscription -
pubsub.topics.create -
pubsub.topics.delete -
pubsub.topics.getIamPolicy -
pubsub.topics.setIamPolicy -
resourcemanager.projects.setIamPolicy -
storage.buckets.create -
storage.buckets.delete -
storage.buckets.update -
storage.objects.delete
-
Dataflow 管理者(
CDC の移行を設定する
Spanner には、CDC を設定し、後で CDC の移行を完了するための Terraform テンプレートが用意されています。Terraform 変数を使用して、テンプレートで Dataflow ジョブの作成を無効にできます。Terraform テンプレートは、次のリソースをデプロイして管理し、CDC の移行を設定します。
Datastream プライベート接続: 構成済みの VPC にプライベート Datastream プライベート接続がデプロイされます。
ソース Datastream 接続プロファイル: Datastream がソース MySQL インスタンスに接続できるようにする接続プロファイル。
Cloud Storage バケット: Datastream がデータを書き込む Cloud Storage バケット。
転送先の Datastream 接続プロファイル: この接続プロファイルを使用すると、Datastream は Cloud Storage バケットに接続して書き込むことができます。
Datastream ストリーム: ソース MySQL インスタンスから読み取り、接続プロファイルで定義されているように Cloud Storage バケットに書き込む Datastream ストリーム。
Pub/Sub トピックとサブスクリプション: Cloud Storage バケットはオブジェクト通知を Pub/Sub トピックに送信し、Dataflow は Pub/Sub サブスクリプションを使用して Spanner にデータを書き込みます。
Cloud Storage バケット通知: Pub/Sub トピックにパブリッシュされる Cloud Storage バケットの通知。
CDC の Terraform 構成の準備
Terraform テンプレートに Dataflow 変数の構成を含める一方で、Dataflow ジョブの作成を無効にするよう準備できます。
common_params = {
project = "PROJECT_ID"
region = "GCP_REGION"
}
datastream_params = {
mysql_host = "MYSQL_HOST_IP_ADDRESS"
mysql_username = "MYSQL_USERNAME"
mysql_password = "MYSQL_PASSWORD"
mysql_port = 3306
mysql_database = {
database = "DATABASE_NAME"
}
private_connectivity = {
vpc_name = "VPC_NAME"
range = "RESERVED_RANGE"
}
}
dataflow_params = {
skip_dataflow = false
enable_backfill = false
template_params = {
spanner_database_id = "SPANNER_DATABASE_ID"
spanner_instance_id = "SPANNER_INSTANCE_ID"
}
runner_params = {
max_workers = 10
num_workers = 4
on_delete = "cancel"
network = "VPC_NETWORK"
subnetwork = "SUBNETWORK_NAME"
}
}
Terraform 変数は次のとおりです。
project: Google Cloud プロジェクト ID。region: Google Cloud のリージョン。mysql_host: ソース MySQL インスタンスの IP アドレス。mysql_username: ソース MySQL インスタンスのユーザー名。mysql_password: ソース MySQL インスタンスのパスワード。mysql_port: ソース MySQL インスタンスのポート番号。database: インスタンス内のソース MySQL データベースの名前。vpc_name: Datastream で使用される既存の VPC の名前。range: Datastream で使用するために予約した VPC の IP 範囲。skip_dataflow: この値をtrueに設定すると、Dataflow ジョブの作成が無効になります。enable_backfill: Terraform テンプレートで Dataflow ジョブの作成を無効にするには、この値をfalseに設定します。spanner_database_id: ターゲット Spanner データベース ID。spanner_instance_id: ターゲット Spanner インスタンス ID。max_workers: Dataflow が作成するワーカーの最大数を決定します。min_workers: Dataflow が作成するワーカーの最大数を決定します。network: Dataflow で使用される既存の VPC の名前。subnetwork: Dataflow がワーカーを作成できる VPC 内の指定されたサブネットワークの名前。
CDC の Terraform テンプレートを実行する
CDC の移行を行うには、Terraform テンプレートを実行する必要があります。
次のコマンドを使用して Terraform を初期化します。
terraform init
次のコマンドを使用して、Terraform ファイルを検証します。
terraform plan --var-file=terraform_simple.tfvars
次のコマンドを使用して Terraform 構成を実行します。
terraform apply --var-file=terraform_simple.tfvars
Terraform 構成によって、次のような出力が生成されます。
Outputs: resource_ids = { "datastream_source_connection_profile" = "source-mysql-thorough-wombat" "datastream_stream" = "mysql-stream-thorough-wombat" "datastream_target_connection_profile" = "target-gcs-thorough-wombat" "gcs_bucket" = "live-migration-thorough-wombat" "pubsub_subscription" = "live-migration-thorough-wombat-sub" "pubsub_topic" = "live-migration-thorough-wombat" } resource_urls = { "datastream_source_connection_profile" = "https://console.cloud.google.com/datastream/connection-profiles/locations/us-central1/instances/source-mysql-thorough-wombat?project=your-project-here" "datastream_stream" = "https://console.cloud.google.com/datastream/streams/locations/us-central1/instances/mysql-stream-thorough-wombat?project=your-project-here" "datastream_target_connection_profile" = "https://console.cloud.google.com/datastream/connection-profiles/locations/us-central1/instances/target-gcs-thorough-wombat?project=your-project-here" "gcs_bucket" = "https://console.cloud.google.com/storage/browser/live-migration-thorough-wombat?project=your-project-here" "pubsub_subscription" = "https://console.cloud.google.com/cloudpubsub/subscription/detail/live-migration-thorough-wombat-sub?project=your-project-here" "pubsub_topic" = "https://console.cloud.google.com/cloudpubsub/topic/detail/live-migration-thorough-wombat?project=your-project-here" }
CDC が Datastream により Cloud Storage バケットにストリーミングされるようになりました。バックフィルの移行を実行してから CDC の移行を完了する必要があります。
バックフィルの移行を実行する
Spanner には、バックフィルの移行を実行する Terraform テンプレートが用意されています。Terraform テンプレートは、次のリソースをデプロイして管理します。
- Dataflow ジョブ: ソース MySQL インスタンスから読み取り、ターゲット Spanner データベースに書き込む Dataflow ジョブ。
バックフィルの移行の Terraform 構成を準備する
job_name = "JOB_NAME"
project = "PROJECT_ID"
region = "GCP_REGION"
working_directory_bucket = "WORKING_DIRECTORY_BUCKET"
working_directory_prefix = "WORKING_DIRECTORY_PREFIX"
source_config_url = "SOURCE_CONFIG_URL"
username = "USERNAME"
password = "PASSWORD"
instance_id = "SPANNER_INSTANCE_ID"
database_id = "SPANNER_DATABASE_ID"
spanner_project_id = "SPANNER_PROJECT_ID"
Terraform 変数は次のとおりです。
job_name: Dataflow ジョブ名。project: Dataflow ジョブを実行する必要がある Google Cloud プロジェクト ID。region: Google Cloud のリージョン。working_directory_bucket: セッション ファイルをアップロードして出力ディレクトリを作成する Cloud Storage バケット。working_directory_prefix: Dataflow 作業ディレクトリの Cloud Storage バケット接頭辞。source_config_url: ソース MySQL インスタンスの IP アドレス。username: ソース MySQL インスタンスのユーザー名。password: ソース MySQL インスタンスのパスワード。instance_id: ターゲット Spanner インスタンス ID。database_id: ターゲット Spanner データベース ID。spanner_project_id: Spanner インスタンスがあるプロジェクト ID。このプロジェクト ID は、Dataflow を実行しているプロジェクトとは異なる場合があります。
バックフィルの移行のための Terraform テンプレートを実行する
バックフィルの移行を実行する手順は次のとおりです。
次のコマンドを使用して Terraform を初期化します。
terraform init
次のコマンドを使用して、Terraform ファイルを検証します。
terraform plan --var-file=terraform_simple.tfvars
次のコマンドを使用して Terraform 構成を実行します。
terraform apply --var-file=terraform_simple.tfvars
Terraform 構成により、次のような出力が生成されます。
Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: dataflow_job_id = [ "2024-06-05_00_41_11-4759981257849547781", ] dataflow_job_url = [ "https://console.cloud.google.com/dataflow/jobs/gcp-region/2024-06-05_00_41_11-4759981257849547781", ]
バックフィルの移行で Spanner に行を書き込むことができない場合、その行は Cloud Storage バケットのデッドレター キュー ディレクトリに書き込まれます。
CDC の移行を完了する前に、デッドレター キュー ディレクトリから Spanner へのこれらの行の書き込みを再試行できます。
CDC の移行を完了する前に、これらの行のデッドレター キュー ディレクトリから Spanner への書き込みを再試行するには、次のコマンドを実行します。
gcloud dataflow flex-template run JOB_NAME \ --region=GCP_REGION \ --template-file-gcs-location=gs://dataflow-templates/latest/flex/Cloud_Datastream_to_Spanner \ --additional-experiments=use_runner_v2 \ --parameters inputFilePattern=inputFilePattern,streamName="ignore", \ --datastreamSourceType=SOURCE_TYPE\ instanceId=INSTANCE_ID,databaseId=DATABASE_ID,sessionFilePath=SESSION_FILE_PATH, \ deadLetterQueueDirectory=DLQ_DIRECTORY,runMode="retryDLQ"
gcloud CLI コマンドの変数は次のとおりです。
job_name: Dataflow ジョブ名。region: Google Cloud のリージョン。inputFilePattern: 入力ファイル パターンの Cloud Storage バケットのロケーション。datastreamSourceType: ソースタイプ(MySQL など)。instanceId: ターゲット Spanner インスタンス ID。databaseId: ターゲット Spanner データベース ID。sessionFilePath: セッション ファイルへの Cloud Storage バケットパス。deadLetterQueueDirectory: DLQ ディレクトリへの Cloud Storage バケットパス。
CDC の移行を完了する
バックフィルの移行が完了したら、Dataflow を使用して CDC を Spanner に移行できます。Dataflow ジョブは、Cloud Storage バケットから変更イベントを受け取り、Spanner に書き込みます。
Cloud Storage バケットのほぼすべてのデータが Spanner に書き込まれたら、移行元の MySQL インスタンスでの書き込みを停止して、残りの変更を Spanner に書き込みます。
これにより、Spanner がソース MySQL インスタンスに追いつくまでの間、短いダウンタイムが発生します。すべての変更が Spanner に書き込まれたら、アプリケーションは Spanner をデータベースとして使用できます。
CDC の移行を完了するには、Terraform パラメータ skip_dataflow の値を false に変更し、ライブ マイグレーションの Terraform テンプレートを再実行します。
次のコマンドを使用して Terraform 構成を実行します。
terraform apply --var-file=terraform_simple.tfvars