本文档介绍了如何使用 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 迁移。
您可以按照以下步骤执行实时数据迁移:
执行实时数据迁移需要部署和管理大量资源。Spanner 为实时数据迁移的每个阶段提供了两个 Terraform 示例模板。
实时迁移模板会分两个阶段执行 CDC 迁移:
- 使用 Datastream 设置将 CDC 迁移到 Cloud Storage 存储分区。 您可以使用 Terraform 变量来阻止模板创建 Dataflow 作业。
- 使用 Dataflow 将 CDC 从 Cloud Storage 存储分区迁移到 Spanner。只有在回填迁移 Terraform 模板完成回填迁移后,您才能执行此阶段。
回填迁移 Terraform 模板会从源 MySQL 实例执行回填迁移到 Spanner。
准备工作
- 确保在本地 shell 中安装了 Terraform。
- 创建一个服务账号以运行实时数据迁移。如需详细了解如何创建服务账号,请参阅创建服务账号。
-
为确保服务账号具有执行实时迁移所需的权限,请让您的管理员为服务账号授予项目的以下 IAM 角色:
-
Dataflow Admin (
roles/dataflow.admin
) -
Datastream Admin (
roles/datastream.admin
) -
Security Admin (
roles/iam.securityAdmin
) -
Service Account Admin (
roles/serviceAccountAdmin
) -
Pub/Sub Admin (
roles/pubsub.admin
) -
Storage Admin (
roles/storage.admin
) -
Compute Network Admin (
roles/compute.networkAdmin
) -
Viewer (
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 Admin (
设置 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 模板:
使用以下命令初始化 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" }
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 模板
如需执行回填迁移,请执行以下操作:
使用以下命令初始化 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 迁移,请将 skip_dataflow
Terraform 参数的值更改为 false
,然后重新运行实时迁移 Terraform 模板。
使用以下命令运行 Terraform 配置:
terraform apply --var-file=terraform_simple.tfvars