本文档介绍了如何使用 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 迁移。
您可以按照以下步骤执行实时数据迁移:
执行实时数据迁移需要部署和管理大量资源。Spanner 为实时数据迁移的每个阶段提供了两个示例 Terraform 模板。
实时迁移模板分两个阶段执行 CDC 迁移:
- 使用 Datastream 设置 CDC 迁移到 Cloud Storage 存储桶。 您可以使用 Terraform 变量来阻止模板创建 Dataflow 作业。
- 使用 Dataflow 将 Cloud Storage 存储桶中的 CDC 迁移到 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 专用连接:专用 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 模板:
使用以下命令初始化 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