本文說明如何使用 Terraform 部署 Dataflow 和 Datastream,將來源 MySQL 執行個體的資料即時遷移至 Spanner,並盡可能縮短停機時間。
執行即時資料遷移作業後,如果您確信所有資料都已轉移、程式碼和依附元件都已遷移,且測試也已完成,就可以將應用程式切換為使用 Spanner,而非來源 MySQL 資料庫。
建立目標 Spanner 資料庫後,即可執行即時資料移轉。遷移資料前,您需要在目標資料庫中建立相容的結構定義。
運作方式
即時資料遷移包含下列兩個階段:
補充並遷移:
- 在補充遷移期間,Dataflow 會從來源 MySQL 資料庫讀取現有資料,並將資料遷移至目標 Spanner 資料庫。您必須使用大量遷移 Dataflow 範本,將資料從來源 MySQL 執行個體遷移至 Spanner。
- 如果回填遷移作業無法將資料列寫入 Spanner,就會將該資料列寫入 Cloud Storage bucket 中的無效信件佇列 (DLQ) 目錄。您可以讓補充遷移作業重試將這些資料列寫入 Spanner。
變更資料擷取 (CDC) 遷移:
- 這個階段會與回填遷移作業同時執行,即時擷取來源 MySQL 執行個體發生的變更。回填遷移作業完成後,這些變更就會套用至 Spanner。
- 您需要使用 Datastream 即時擷取來源 MySQL 執行個體發生的變更,並將這些變更寫入 Cloud Storage bucket。
- 回填遷移作業完成後,您需要使用 Dataflow,將 CDC 從 Cloud Storage bucket 移至 Spanner。如果 Dataflow 因故無法將資料列寫入 Spanner,就會將該資料列寫入另一個 Cloud Storage 值區的 DLQ 目錄。CDC 遷移作業會自動重試,將 DLQ 目錄中的資料列寫入 Spanner。
規劃即時資料遷移
您需要設定網路基礎架構,讓資料在來源 MySQL 執行個體、Datastream、Dataflow、Cloud Storage bucket 和目標 Spanner 資料庫之間流動。建議設定私人網路連線,確保遷移作業安全無虞。 視貴機構的法規遵循需求而定,您可能需要設定公用或私人網路連線。如要進一步瞭解 Datastream 連線,請參閱「網路連線選項」。
如要規劃即時資料遷移作業,您可能需要貴機構的網路管理員執行下列工作:
- 使用預設虛擬私有雲,或在專案中建立新的虛擬私有雲,並符合下列要求:
- 來源 MySQL 執行個體必須位於這個 VPC 中。 您可能需要在這個虛擬私有雲上建立輸出防火牆規則,並在來源 MySQL 執行個體所在的虛擬私有雲上建立輸入防火牆規則。
- Datastream、Dataflow、Cloud Storage bucket 和目標 Spanner 資料庫必須在這個虛擬私有雲中可用。
- 您必須在來源 MySQL 執行個體上建立許可清單,允許來自虛擬私有雲的連線。
- 在虛擬私有雲中決定並分配 Datastream 可用的 IP 位址範圍。
- 在虛擬私有雲中建立子網路,供 Dataflow 用於完成回填遷移作業。
- 在虛擬私有雲中建立子網路,供 Dataflow 稍後完成 CDC 遷移作業。
如要執行即時資料遷移,請按照下列步驟操作:
執行即時資料遷移作業時,必須部署及管理大量資源。Spanner 為即時資料遷移的每個階段提供兩個 Terraform 範本。
即時遷移範本會分兩個階段執行 CDC 遷移:
- 使用 Datastream 設定 CDC 遷移作業,將資料遷移至 Cloud Storage bucket。您可以使用 Terraform 變數,防止範本建立 Dataflow 工作。
- 使用 Dataflow,將 CDC 從 Cloud Storage bucket 遷移至 Spanner。只有在回填移轉 Terraform 範本完成回填移轉後,您才能執行這個階段。
補充遷移 Terraform 範本會執行補充遷移作業,將資料從來源 MySQL 執行個體遷移至 Spanner。
事前準備
- 確認本機殼層已安裝 Terraform。
- 建立服務帳戶,用於執行即時資料移轉。如要進一步瞭解如何建立服務帳戶,請參閱「建立服務帳戶」。
-
為確保服務帳戶具備執行即時遷移作業所需的權限,請要求管理員在專案中,將下列 IAM 角色授予服務帳戶:
- Dataflow 管理員 (
roles/dataflow.admin) - Datastream 管理員 (
roles/datastream.admin) - 安全管理員 (
roles/iam.securityAdmin) - 服務帳戶管理員 (
roles/iam.serviceAccountAdmin) - Pub/Sub 管理員 (
roles/pubsub.admin) - 儲存空間管理員 (
roles/storage.admin) - Compute 網路管理員 (
roles/compute.networkAdmin) - 檢視者 (
roles/viewer)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。
這些預先定義的角色具備執行即時遷移所需的權限。如要查看確切的必要權限,請展開「Required permissions」(必要權限) 部分:
所需權限
如要執行即時遷移,必須具備下列權限:
-
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 提供 Terraform 範本,可設定 CDC,並在稍後完成 CDC 遷移作業。您可以使用 Terraform 變數,停用範本建立 Dataflow 工作的功能。Terraform 範本會部署及管理下列資源,以設定 CDC 遷移作業:
Datastream 私人連線:Datastream 私人連線會部署在您設定的虛擬私有雲中。
來源 Datastream 連線設定檔:連線設定檔,可讓 Datastream 連線至來源 MySQL 執行個體。
Cloud Storage bucket:Datastream 寫入資料的 Cloud Storage bucket。
目標 Datastream 連線設定檔:這個連線設定檔可讓 Datastream 連線及寫入 Cloud Storage bucket。
Datastream 串流:Datastream 串流,會從來源 MySQL 執行個體讀取資料,並寫入連線設定檔中定義的 Cloud Storage bucket。
Pub/Sub 主題和訂閱項目:Cloud Storage bucket 會將物件通知傳送至 Pub/Sub 主題,Dataflow 則會使用 Pub/Sub 訂閱項目將資料寫入 Spanner。
Cloud Storage bucket 通知:發布至 Pub/Sub 主題的 Cloud Storage bucket 通知。
準備 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"
}
}
更改下列內容:
PROJECT_ID: Google Cloud 專案 ID。GCP_REGION:您要執行 Dataflow 工作的 Google Cloud 區域。MYSQL_HOST_IP_ADDRESS:來源 MySQL 執行個體 IP 位址。MYSQL_USERNAME:來源 MySQL 執行個體的使用者名稱。MYSQL_PASSWORD:來源 MySQL 執行個體密碼。DATABASE_NAME:執行個體中的來源 MySQL 資料庫名稱。VPC_NAME:Datastream 使用的現有虛擬私有雲名稱。RESERVED_RANGE:您為 Datastream 預留的虛擬私有雲 IP 位址範圍。SPANNER_DATABASE_ID:目標 Spanner 資料庫 ID。SPANNER_INSTANCE_ID:目標 Spanner 執行個體 ID。VPC_NETWORK:Dataflow 使用的現有虛擬私有雲名稱。SUBNETWORK_NAME:Dataflow 建立 worker 的虛擬私有雲中,指定子網路的名稱。
執行 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 bucket。您必須執行補充遷移作業,並在稍後完成 CDC 遷移作業。
執行補充並遷移作業
Spanner 提供 Terraform 範本,可執行補充遷移作業。Terraform 範本會部署及管理下列資源:
- Dataflow 工作:Dataflow 工作會從來源 MySQL 執行個體讀取資料,並寫入目標 Spanner 資料庫。
準備補充並遷移的 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"
更改下列內容:
JOB_NAME:Dataflow 工作的名稱。PROJECT_ID:執行 Dataflow 工作的 Google Cloud 專案 ID。GCP_REGION:您要執行 Dataflow 工作的 Google Cloud 區域。WORKING_DIRECTORY_BUCKET:用於上傳工作階段檔案及建立輸出目錄的 Cloud Storage bucket。WORKING_DIRECTORY_PREFIX:Dataflow 目前使用的目錄 Cloud Storage bucket 前置字元。SOURCE_CONFIG_URL:來源 MySQL 執行個體 IP 位址。USERNAME:來源 MySQL 執行個體的使用者名稱。PASSWORD:來源 MySQL 執行個體密碼。SPANNER_INSTANCE_ID:目標 Spanner 執行個體 ID。SPANNER_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 bucket 中的無效信件佇列目錄。
在完成 CDC 遷移作業前,您可以重試將這些資料列從無效信件佇列目錄寫入 Spanner。
如要在完成 CDC 遷移作業前,將這些資料列從死信佇列目錄重新寫入 Spanner,請執行下列指令:
gcloud dataflow flex-template run JOB_NAME \
--project=PROJECT_ID \
--region=GCP_REGION \
--template-file-gcs-location=gs://dataflow-templates/latest/flex/Cloud_Datastream_to_Spanner \
--additional-experiments=use_runner_v2 \
--parameters inputFilePattern=INPUT_FILE_PATTERN,\
streamName="ignore",\
datastreamSourceType=SOURCE_TYPE,\
instanceId=INSTANCE_ID,databaseId=DATABASE_ID,sessionFilePath=SESSION_FILE_PATH,\
deadLetterQueueDirectory=DLQ_DIRECTORY,\
runMode="retryDLQ"
更改下列內容:
JOB_NAME:Dataflow 工作名稱。PROJECT_ID:執行 Dataflow 工作的 Google Cloud 專案 ID。GCP_REGION:您要執行 Dataflow 工作的 Google Cloud 區域。INPUT_FILE_PATTERN:輸入檔案模式的 Cloud Storage bucket 位置。SOURCE_TYPE:來源資料庫類型 (例如mysql)。INSTANCE_ID:目標 Spanner 執行個體 ID。DATABASE_ID:目標 Spanner 資料庫 ID。SESSION_FILE_PATH:Spanner 遷移工具產生的工作階段檔案的 Cloud Storage 路徑。DLQ_DIRECTORY:Cloud Storage 中死信佇列根目錄的路徑,該目錄包含要重試的錯誤檔案 (例如gs://MIGRATION_BUCKET/ENV/SERVICE/cdc/DB_SCHEMA/)。
執行 CDC 遷移作業
完成補充遷移作業後,您可以使用 Dataflow 將 CDC 遷移至 Spanner。Dataflow 工作會從 Cloud Storage bucket 擷取變更事件,並寫入 Spanner。
如要執行 CDC 遷移作業,請將 skip_dataflow Terraform 參數的值變更為 false,然後重新執行即時遷移 Terraform 範本。
使用下列指令執行 Terraform 設定:
terraform apply --var-file=terraform_simple.tfvars
監控及解決 CDC 錯誤
在從 MySQL 到 Spanner 的即時異動資料擷取 (CDC) 複製作業期間,如果串流 Dataflow 工作無法將變更事件寫入 Spanner,就會將失敗歸入兩種錯誤類別之一,並將記錄寫入 deadLetterQueueDirectory Cloud Storage bucket 中的 DLQ 目錄:
可重試的錯誤:暫時性失敗,包括但不限於:
- Spanner 超過期限錯誤
- 違反外鍵和交錯資料表限制。如果子項資料列因網路錯誤或平行處理,而比父項資料列先抵達,就可能發生這種情況。
Dataflow 會將這些事件寫入
retry/DLQ 目錄,並在同一個管道中重試,直到成功或超過重試次數上限。嚴重錯誤:無法透過自動重試解決的永久失敗,包括但不限於下列情況:
- 資料類型轉換錯誤
- 不重複索引違規
- 自訂轉換 JAR 中的例外狀況
Dataflow 會將這些事件寫入
severe/DLQ 目錄,並遞增Total permanent errors自訂使用者計數器。
由於嚴重錯誤無法透過自動重試解決,Dataflow 會從作用中的複製串流中移除這些失敗的事件,並將其儲存在 severe/ 目錄中。如果未處理,目的地 Spanner 資料庫就會缺少這些記錄。在即時遷移期間,請定期監控 Total permanent errors 計數器和 severe/ 目錄,以便在啟動應用程式轉換前,解決並重播失敗的變更事件。
請注意,Dataflow 自訂計數器 Total permanent errors 是累計指標,會記錄串流工作啟動後發生的嚴重錯誤總數。使用 DLQ 重試工作重播及解決失敗記錄時,原始串流管道上的這個計數器不會遞減。因此,Cloud Storage 嚴重 DLQ 目錄 (gs://.../severe/) 是未處理錯誤是否存在的權威單一事實來源。
重播失敗的記錄
如果嚴重 DLQ 目錄中出現失敗記錄,請檢查 Cloud Storage 中的 JSON 錯誤檔案,找出根本原因,並解決 Spanner 中的基礎問題 (例如手動插入缺少的父項記錄,或更新結構定義覆寫對應)。
如要將修正後的 DLQ 記錄重播至 Spanner,請使用下列其中一種 DLQ 重試執行模式,啟動新的 Dataflow 工作:
retryDLQ模式:在執行中的串流管道旁,以批次工作形式執行這個模式,處理severe/目錄中的錯誤檔案,不中斷即時 CDC 複製作業。retryAllDLQ模式:如果一般串流管道已停止,請使用這個模式處理retry/和severe/目錄。請勿在管道處於啟用狀態時同時執行retryAllDLQ,否則會導致檔案爭用和處理衝突。
如要使用 gcloud CLI 啟動 DLQ 重試工作,請執行下列指令:
gcloud dataflow flex-template run RETRY_JOB_NAME \
--project=PROJECT_ID \
--region=GCP_REGION \
--template-file-gcs-location=gs://dataflow-templates/latest/flex/Cloud_Datastream_to_Spanner \
--additional-experiments=use_runner_v2 \
--parameters streamName="ignore",\
datastreamSourceType=SOURCE_TYPE,\
instanceId=INSTANCE_ID,databaseId=DATABASE_ID,sessionFilePath=SESSION_FILE_PATH,\
deadLetterQueueDirectory=DLQ_DIRECTORY,\
runMode="retryDLQ"
更改下列內容:
RETRY_JOB_NAME:Dataflow DLQ 重試工作的名稱。PROJECT_ID:執行 Dataflow 工作的 Google Cloud 專案 ID。GCP_REGION:您要執行 Dataflow 工作的 Google Cloud 區域。SOURCE_TYPE:來源資料庫類型 (例如mysql)。INSTANCE_ID:目標 Spanner 執行個體 ID。DATABASE_ID:目標 Spanner 資料庫 ID。SESSION_FILE_PATH:Spanner 遷移工具產生的工作階段檔案的 Cloud Storage 路徑。DLQ_DIRECTORY:無效信件佇列根目錄的 Cloud Storage 路徑,其中包含要重試的錯誤檔案 (例如gs://MIGRATION_BUCKET/ENV/SERVICE/cdc/DB_SCHEMA/)。
完成 CDC 遷移
Cloud Storage bucket 的資料幾乎都寫入 Spanner 後,請停止寫入來源 MySQL 執行個體,讓剩餘的變更寫入 Spanner。
Spanner 趕上來源 MySQL 執行個體時,會造成短暫的停機時間。所有變更寫入 Spanner 後,應用程式即可開始使用 Spanner 做為資料庫。
如需暫停應用程式寫入、排空傳輸中的資料,以及執行應用程式轉換的詳細逐步說明,請參閱「執行 MySQL 轉換」。