从 MySQL 进行实时数据迁移

本文档介绍了如何使用 Terraform 部署 Dataflow 和 Datastream,以便在停机时间最短的情况下从源 MySQL 实例到 Spanner 执行实时数据迁移。

执行实时数据迁移并确信所有数据都已转移、迁移了代码和依赖项并完成测试后,您可以将应用切换为使用 Spanner 而非源 MySQL 数据库。

创建目标 Spanner 数据库后,您可以执行实时数据迁移。您需要先在目标数据库上创建兼容的架构,然后才能迁移数据。

工作原理

实时数据迁移包括以下两个阶段:

  • 回填迁移

    • 在回填迁移期间,Dataflow 会从源 MySQL 数据库读取现有数据,并将这些数据迁移到目标 Spanner 数据库。您需要使用 Dataflow 批量迁移模板将数据从源 MySQL 实例迁移到 Spanner。
    • 当回填迁移无法将某行写入 Spanner 时,它会将该行写入 Cloud Storage 存储分区中的邮件无法送达队列目录。您可以让回填迁移重试将这些行写入 Spanner。
  • 变更数据捕获 (CDC) 迁移

    • 此阶段与回填迁移并行运行,可实时捕获源 MySQL 实例中发生的更改。然后,在回填迁移完成后,这些更改会应用于 Spanner。
    • 您需要使用 Datastream 实时捕获源 MySQL 实例中发生的更改,并将其写入 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 数据库。
    • 您必须在源 MySQL 实例上创建许可名单,才能允许来自 VPC 的连接。
  • 在 VPC 中确定并分配 Datastream 可用的 IP 地址范围。
  • 在 VPC 中创建一个子网,供 Dataflow 用于完成回填迁移。
  • 在 VPC 中创建一个子网,以便 Dataflow 稍后用于完成 CDC 迁移。

您可以按照以下步骤执行实时数据迁移:

  1. 设置 CDC 迁移
  2. 执行回填迁移
  3. 在回填迁移完成后完成 CDC 迁移

执行实时数据迁移需要部署和管理大量资源。Spanner 为实时数据迁移的每个阶段提供了两个 Terraform 示例模板。

实时迁移模板会分两个阶段执行 CDC 迁移:

  • 使用 Datastream 设置将 CDC 迁移到 Cloud Storage 存储分区。 您可以使用 Terraform 变量来阻止模板创建 Dataflow 作业。
  • 使用 Dataflow 将 CDC 从 Cloud Storage 存储分区迁移到 Spanner。只有在回填迁移 Terraform 模板完成回填迁移后,您才能执行此阶段。

回填迁移 Terraform 模板会从源 MySQL 实例执行回填迁移到 Spanner。

准备工作

  • 确保在本地 shell 中安装了 Terraform。
  • 创建一个服务账号以运行实时数据迁移。如需详细了解如何创建服务账号,请参阅创建服务账号
  • 为确保服务账号具有执行实时迁移所需的权限,请让您的管理员为服务账号授予项目的以下 IAM 角色:

    如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

    这些预定义角色包含执行实时迁移所需的权限。如需查看所需的确切权限,请展开所需权限部分:

    所需权限

    如需执行实时迁移,您需要具备以下权限:

    • 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

    您的管理员也可以使用自定义角色或其他预定义角色为服务账号授予这些权限。

设置 CDC 迁移

Spanner 提供了一个 Terraform 模板,用于设置 CDC 并随后完成 CDC 迁移。您可以使用 Terraform 变量禁止模板创建 Dataflow 作业。Terraform 模板会部署和管理以下资源,以设置 CDC 迁移:

  • Datastream 专用连接:在您配置的 VPC 上部署 Datastream 专用连接。

  • 来源 Datastream 连接配置文件:一种连接配置文件,可让 Datastream 连接到您的来源 MySQL 实例。

  • Cloud Storage 存储分区:Datastream 将数据写入的 Cloud Storage 存储分区。

  • 目标 Datastream 连接配置文件:此连接配置文件可让 Datastream 连接到 Cloud Storage 存储分区并向其中写入数据。

  • Datastream 数据流:Datastream 数据流会从源 MySQL 实例读取数据,并按照连接配置文件中定义的方式写入 Cloud Storage 存储分区。

  • 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 创建 Dataflow 作业。
  • enable_backfill:将此值设为 false 可禁止 Terraform 模板创建 Dataflow 作业。
  • spanner_database_id:目标 Spanner 数据库 ID。
  • spanner_instance_id:目标 Spanner 实例 ID。
  • max_workers:决定 Dataflow 创建的工作器数量上限。
  • min_workers:用于确定 Dataflow 创建的工作器数量上限。
  • network:Dataflow 将要使用的现有 VPC 的名称。
  • subnetwork:VPC 中指定的子网的名称,Dataflow 可以在其中创建工作器。

运行 CDC Terraform 模板

如需执行 CDC 迁移,您需要运行 Terraform 模板:

  1. 使用以下命令初始化 Terraform:

      terraform init
    

  2. 使用以下命令验证 Terraform 文件:

      terraform plan --var-file=terraform_simple.tfvars
    

  3. 使用以下命令运行 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"
    }
    

Datastream 现在会将 CDC 流式传输到 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 模板

如需执行回填迁移,请执行以下操作:

  1. 使用以下命令初始化 Terraform:

      terraform init
    

  2. 使用以下命令验证 Terraform 文件:

      terraform plan --var-file=terraform_simple.tfvars
    

  3. 使用以下命令运行 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 迁移,请将 skip_dataflow Terraform 参数的值更改为 false,然后重新运行实时迁移 Terraform 模板

使用以下命令运行 Terraform 配置:

      terraform apply --var-file=terraform_simple.tfvars
    

后续步骤