从 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 上创建入站防火墙规则。
    • Datastream、Dataflow、Cloud Storage 存储分区和目标 Spanner 数据库必须在此 VPC 上可用。
    • 您必须在源 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 将 Cloud Storage 存储桶中的 CDC 迁移到 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 专用连接:专用 Datastream 专用连接部署在您配置的 VPC 上。

  • 源 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:您在 VPC 上预留供 Datastream 使用的 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
    

后续步骤