このドキュメントでは、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