將 Hive 代管資料表遷移至 Google Cloud

本文說明如何將 Hive 管理的資料表遷移至 Google Cloud。

您可以使用 BigQuery 資料移轉服務中的 Hive 受管理資料表遷移連接器,將 Hive Metastore 管理的資料表從地端部署和雲端環境無縫遷移至 Google Cloud,支援 Hive 和 Iceberg 格式。Hive 代管資料表遷移連接器支援儲存在下列資料來源中的檔案:

  • HDFS
  • Amazon S3
  • Azure Blob 儲存體或 Azure Data Lake Storage Gen2

使用 Hive 代管資料表遷移連接器時,您可以將 Hive 代管資料表註冊至 Dataproc MetastoreBigLake metastore Iceberg REST 目錄,同時使用 Cloud Storage 做為檔案儲存空間。

這個連接器支援完整轉移和僅轉移中繼資料。完整轉移作業會將來源資料表中的資料和中繼資料,一併轉移至目標中繼資料存放區。如果資料已移轉至 Cloud Storage,您可以只移轉中繼資料。

下圖概略說明從 Hadoop 叢集遷移資料表的程序。

從 Hive 資料湖泊遷移資料表至 BigQuery 的總覽。

限制

Hive 受管理資料表移轉作業有下列限制:

  • 如要遷移 Apache Iceberg 資料表,您必須向 BigLake metastore Iceberg REST 目錄註冊資料表,允許開放原始碼引擎 (例如 Apache Spark 或 Flink) 寫入資料。
  • 如要遷移 Hive 代管資料表,您必須向 Dataproc Metastore 註冊資料表,允許開放原始碼引擎寫入存取權,並允許 BigQuery 讀取存取權。
  • 檔案名稱必須符合 Cloud Storage 物件命名規定
  • 如果資料在移轉作業進行期間於來源端變更,Storage 移轉服務會採取特定行為。我們不建議在資料表遷移期間寫入資料。
  • Cloud Storage 的單一物件大小上限為 5 TiB。如果 Apache Hive 表格中的檔案大於 5 TiB,系統就無法轉移。

如需其他限制的清單,請參閱「Storage 移轉服務已知限制」。

配額和並行限制

從 Hive 受管理資料表移轉資料時,您必須遵守 Storage 移轉服務的配額與限制。詳情請參閱「配額與限制」。

事前準備

排定 Hive 代管資料表轉移作業之前,請先執行下列操作:

產生 Apache Hive 的中繼資料檔案

執行 dwh-migration-dumper 工具,擷取 Apache Hive 的中繼資料。這項工具會產生名為 hive-dumper-output.zip 的檔案,並儲存至 Cloud Storage bucket (本文稱為 DUMPER_BUCKET)。

啟用 API

在Google Cloud 專案中啟用下列 API

  • Data Transfer API
  • Storage Transfer API

啟用 Data Transfer API 時,系統會建立服務代理程式

設定權限

  1. 建立服務帳戶,並授予 BigQuery 管理員角色 (roles/bigquery.admin)。這個服務帳戶用於建立移轉設定。
  2. 啟用 Data Transfer API 時,系統會建立服務代理人 (P4SA)。為服務帳戶指派下列角色:

    • roles/metastore.metadataOwner
    • roles/storagetransfer.admin
    • roles/serviceusage.serviceUsageConsumer
    • roles/storage.objectAdmin
    • roles/storage.admin
      • 如果您要將中繼資料遷移至 BigLake metastore Iceberg REST Catalog,也必須授予 roles/biglake.admin 角色。
  3. 使用下列指令,將 roles/iam.serviceAccountTokenCreator 角色授予服務代理程式:

    gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT --member serviceAccount:service-PROJECT_NUMBER@gcp-sa-bigquerydatatransfer.iam.gserviceaccount.com --role roles/iam.serviceAccountTokenCreator
  4. 在專案中,將下列角色授予 Storage 移轉服務服務代理程式 (project-<var>PROJECT_NUMBER</var>@storage-transfer-service.iam.gserviceaccount.com):

    • roles/storage.admin
    • 如果您要從 HDFS 遷移,也必須授予 roles/storagetransfer.serviceAgent 角色。

    您也可以設定更精細的權限。詳情請參閱來源專屬的權限指南:

設定 HDFS 資料湖泊的 Storage Transfer Agent

如果檔案儲存在 HDFS 中,則為必要項目。如要設定 HDFS 資料湖泊移轉作業所需的儲存空間移轉代理程式,請按照下列步驟操作:

  1. 在內部部署代理程式機器上安裝 Docker
  2. 在 Google Cloud 專案中建立 Storage 移轉服務代理程式集區
  3. 在您的地端部署代理程式電腦上安裝代理程式

設定 Amazon S3 的 Storage 移轉服務權限

如果檔案儲存在 Amazon S3,則為必填欄位。從 Amazon S3 轉移資料時,不需要代理程式,但需要特定權限。如要設定 Storage 移轉服務以進行 Amazon S3 移轉作業,請按照下列步驟操作:

  1. 設定 AWS Amazon S3 的存取憑證
    • 設定存取憑證後,請記下存取金鑰 ID 和私密存取金鑰。
  2. 如果 AWS 專案使用 IP 限制,請將 Storage 移轉服務 工作人員使用的 IP 範圍加入 IP 許可清單。

設定 Microsoft Azure 儲存體的 Storage 移轉服務權限

如果檔案儲存在 Azure Blob 儲存體或 Azure Data Lake Storage Gen2,則必須提供這項資訊。從 Microsoft Azure Storage 轉移資料時,不需要代理程式,但需要特定權限。如要設定 Storage Transfer Service,以便移轉 Microsoft Azure 儲存空間,請按照下列步驟操作:

  1. 為 Microsoft Azure 儲存體帳戶產生共用存取簽章 (SAS) 權杖
    • 產生 SAS 權杖後,請記下權杖。
  2. 如果 Microsoft Azure 儲存空間帳戶使用 IP 限制,請將 Storage 移轉服務工作站使用的 IP 範圍加入 IP 許可清單。

排定 Hive 代管資料表轉移作業

選取下列選項之一:

控制台

  1. 前往 Google Cloud 控制台的「資料移轉」頁面。

    前往「資料轉移」頁面

  2. 按一下 「建立轉移作業」

  3. 在「來源類型」部分,從「來源」清單中選取「Hive Managed Tables」

  4. 在「位置」下方選取位置類型,然後選取區域。

  5. 在「Transfer config name」(轉移設定名稱) 部分,「Display name」(顯示名稱) 請輸入資料移轉作業的名稱。

  6. 在「Schedule options」(排程選項) 部分執行下列操作:

    • 在「Repeat frequency」(重複頻率) 清單選取選項,指定這項資料移轉作業的執行頻率。如要指定自訂重複頻率,請選取「Custom」(自訂)。如果選取「On-demand」(隨選),這項移轉作業會在您手動觸發後執行。
    • 視情況選取「Start now」(立即開始) 或「Start at set time」(在所設時間開始執行),並提供開始日期和執行時間。
  7. 在「Data source details」(資料來源詳細資料) 部分執行下列操作:

    1. 在「轉移策略」中,選取下列任一選項:
      • FULL_TRANSFER:轉移所有資料,並向目標中繼存放區註冊中繼資料。這是預設選項。
      • METADATA_ONLY:僅註冊中繼資料。您必須在元資料中參照的正確 Cloud Storage 位置中,預先存有資料。
    2. 在「Table name patterns」(資料表名稱格式) 部分,提供符合 HDFS 資料庫中資料表的名稱或格式,指定要轉移的 HDFS 資料湖泊資料表。您必須使用 Java 規則運算式語法指定表格模式。例如:
      • db1..* 會比對 db1 中的所有資料表。
      • db1.table1;db2.table2 會比對 db1 中的 table1 和 db2 中的 table2。
    3. 在「BQMS discovery dump gcs path」(BQMS 探索傾印 GCS 路徑) 中,輸入您在建立 Apache Hive 的中繼資料檔案時產生的 hive-dumper-output.zip 檔案路徑。如果您使用 dumper 輸出內容協調與 cron,請提供 --gcs-base-path 中設定的 Cloud Storage 資料夾路徑,其中包含 dumper 輸出內容 ZIP 檔案。
    4. 從下拉式清單中選擇 Metastore 類型:
      • DATAPROC_METASTORE:選取這個選項,將中繼資料儲存在 Dataproc Metastore 中。您必須在「Dataproc metastore url」(Dataproc Metastore 網址) 中提供 Dataproc Metastore 的網址。
      • BIGLAKE_REST_CATALOG:選取這個選項,將中繼資料儲存在 BigLake metastore Iceberg REST 目錄中。
    5. 「Destination gcs path」(目的地 GCS 路徑) 中,輸入 Cloud Storage bucket 的路徑,用來儲存遷移的資料。

    6. 選用:在「服務帳戶」中,輸入要用於這項資料移轉作業的服務帳戶。服務帳戶應屬於建立移轉設定和目的地資料集的相同Google Cloud 專案。

    7. 在「儲存空間類型」中,選取下列其中一個選項。只有在「轉移策略」設為 FULL_TRANSFER 時,才能使用這個欄位:

      • HDFS:如果檔案儲存空間是 HDFS,請選取這個選項。在「STS agent pool name」(STS 代理程式集區名稱) 欄位中,您必須提供設定 Storage Transfer Agent 時建立的代理程式集區名稱。
      • S3:如果檔案儲存空間是 Amazon S3,請選取這個選項。在「Access key ID」(存取金鑰 ID) 和「Secret access key」(私密存取金鑰) 欄位中,您必須提供設定存取憑證時建立的存取金鑰 ID 和私密存取金鑰。
      • AZURE:如果檔案儲存空間是 Azure Blob Storage,請選取這個選項。在「SAS token」(SAS 權杖) 欄位,請提供您設定存取憑證時建立的 SAS 權杖。
    8. 選用:在「Partition Filter gcs path」(分區篩選器 GCS 路徑) 欄位中,輸入自訂篩選器 JSON 檔案的完整 Cloud Storage 路徑,即可篩選分區

bq

如要排定 Hive 受管理資料表移轉作業,請輸入 bq mk 指令並加上移轉建立作業旗標 --transfer_config

  bq mk --transfer_config
  --data_source=hadoop
  --display_name='TRANSFER_NAME'
  --service_account_name='SERVICE_ACCOUNT'
  --project_id='PROJECT_ID'
  --location='REGION'
  --params='{
    "transfer_strategy":"TRANSFER_STRATEGY",
    "table_name_patterns":"LIST_OF_TABLES",
    "table_metadata_path":"gs://DUMPER_BUCKET/hive-dumper-output.zip",
    "target_gcs_file_path":"gs://MIGRATION_BUCKET",
    "metastore":"METASTORE",
    "destination_dataproc_metastore":"DATAPROC_METASTORE_URL",
    "destination_bigquery_dataset":"BIGLAKE_METASTORE_DATASET",
    "translation_output_gcs_path":"gs://TRANSLATION_OUTPUT_BUCKET/metadata/config/default_database/",
    "storage_type":"STORAGE_TYPE",
    "agent_pool_name":"AGENT_POOL_NAME",
    "aws_access_key_id":"AWS_ACCESS_KEY_ID",
    "aws_secret_access_key":"AWS_SECRET_ACCESS_KEY",
    "azure_sas_token":"AZURE_SAS_TOKEN",
    "partition_filter_gcs_path":"FILTER_GCS_PATH"
    }'

更改下列內容:

  • TRANSFER_NAME:移轉設定的顯示名稱。移轉作業名稱可以是任意值,日後需要修改移轉作業時,能夠據此識別即可。
  • SERVICE_ACCOUNT:用於驗證轉移作業的服務帳戶名稱。服務帳戶應由用於建立轉移作業的 project_id 擁有,且應具備所有必要權限。
  • PROJECT_ID:您的 Google Cloud 專案 ID。如未提供 --project_id 指定特定專案,系統會使用預設專案。
  • REGION:這項移轉設定的位置。
  • TRANSFER_STRATEGY:(選用) 指定下列其中一個值:
    • FULL_TRANSFER:轉移所有資料,並向目標中繼存放區註冊中繼資料。這是預設值。
    • METADATA_ONLY:僅註冊中繼資料。您必須在元資料中參照的正確 Cloud Storage 位置中,預先存有資料。
  • LIST_OF_TABLES:要轉移的實體清單。使用階層式命名規格 - database.table。這個欄位支援 RE2 規則運算式,可指定資料表。例如:
    • db1..*:指定資料庫中的所有資料表
    • db1.table1;db2.table2:資料表清單
  • DUMPER_BUCKET:包含 hive-dumper-output.zip 檔案的 Cloud Storage bucket。如果您使用傾印程式輸出內容協調與 cron,請將 table_metadata_path 變更為使用 cron 設定中的 --gcs-base-path 設定的 Cloud Storage 資料夾路徑,例如:"table_metadata_path":"<var>GCS_PATH_TO_UPLOAD_DUMPER_OUTPUT</var>"
  • MIGRATION_BUCKET:所有基礎檔案的載入目的地 GCS 路徑。只有在 transfer_strategyFULL_TRANSFER 時,才能使用這項功能。
  • METASTORE:要遷移的 Metastore 類型。請將此值設為下列其中一個值:
    • DATAPROC_METASTORE:將中繼資料轉移至 Dataproc Metastore。
    • BIGLAKE_REST_CATALOG:將中繼資料轉移至 BigLake Metastore Iceberg REST 目錄。
  • DATAPROC_METASTORE_URL:Dataproc Metastore 的網址。如果 metastoreDATAPROC_METASTORE,則為必要欄位。
  • BIGLAKE_METASTORE_DATASET:BigLake 中繼存放區的 BigQuery 資料集。如果 metastoreBIGLAKE_METASTOREtransfer_strategyFULL_TRANSFER,則為必要欄位。
  • STORAGE_TYPE:指定資料表的基礎檔案儲存空間。支援的類型為 HDFSS3AZURE。如果 transfer_strategyFULL_TRANSFER,則為必要欄位。
  • AGENT_POOL_NAME:用於建立代理程式的代理程式集區名稱。如果 storage_typeHDFS,則為必要欄位。
  • AWS_ACCESS_KEY_ID存取憑證中的存取金鑰 ID。如果 storage_typeS3,則為必要欄位。
  • AWS_SECRET_ACCESS_KEY存取憑證中的私密存取金鑰。如果 storage_typeS3,則為必要欄位。
  • AZURE_SAS_TOKEN:來自存取憑證的 SAS 權杖。如果 storage_typeAZURE,則為必要欄位。
  • FILTER_GCS_PATH:(選用) 自訂篩選器 JSON 檔案的完整 Cloud Storage 路徑,用於篩選分割區

執行這項指令,建立移轉設定並開始移轉 Hive 受管理資料表。根據預設,系統每隔 24 小時就會執行移轉作業,但您可以使用移轉排程選項進行設定。

轉移完成後,Hadoop 叢集中的資料表就會遷移至 MIGRATION_BUCKET

資料擷取選項

以下各節提供更多資訊,說明如何設定 Hive 受管理資料表移轉作業。

增量移轉

如果移轉設定設有週期性時間表,後續每次移轉都會更新 Google Cloud 上的資料表,反映來源資料表的最新變更。舉例來說,所有插入、刪除或更新作業 (含結構定義變更) 都會反映在 Google Cloud 中,每次轉移都會更新。

轉移排程選項

根據預設,系統會排定每 24 小時執行一次移轉作業。如要設定移轉作業的執行頻率,請在移轉設定中加入 --schedule 標記,並使用schedule 語法指定移轉時間表。 Hive 受管理資料表轉移作業的執行間隔至少須為 24 小時。

如要進行一次性移轉,您可以在移轉設定中加入 end_time 旗標,只執行一次移轉。

篩選分區

您可以提供儲存在 Cloud Storage 中的自訂篩選器 JSON 檔案,從 Hive 管理的資料表移轉部分分區。排定轉移作業時,請使用 partition_filter_gcs_path 參數,提供這個 JSON 檔案的完整 Cloud Storage 路徑。

以下是篩選器 JSON 檔案結構範例:

{
  "filters": [
    {
      "table": "db1.table1",
      "condition": "IN",
      "partition": ["partition1=value1/partition2=value2"]
    },
    {
      "table": "db1.table2",
      "condition": "LESS_THAN",
      "partition": ["partition1;value1"]
    },
    {
      "table": "db1.table3",
      "condition": "GREATER_THAN",
      "partition": ["partition1;value1"]
    },
    {
      "table": "db1.table4",
      "condition": "RANGE",
      "partition": ["partition1;value1;value2"]
    }
  ]
}

篩選條件

JSON 檔案中的 condition 欄位支援下列值,每個值都有 partition 陣列的特定格式:

  • IN:指定要納入的確切分割區路徑。partition 陣列包含字串,代表相對於資料表基本路徑的分割區確切目錄結構 (例如 ["partition_key1=value1/partition_key2=value2"])。您可以在陣列中指定多個路徑。
  • LESS_THAN:包含主要分區鍵值小於或等於指定值的分區。partition 陣列必須包含格式為 ["<partition_key>;<value>"] 的單一字串。
  • GREATER_THAN:包含主要分區鍵值大於或等於指定值的分區。partition 陣列必須包含格式為 ["<partition_key>;<value>"] 的單一字串。
  • RANGE:包含主要分區鍵值落在指定範圍內 (含) 的分區。partition 陣列必須包含格式為 ["<partition_key>;<start_value>;<end_value>"] 的單一字串。

篩選條件須遵守下列規則和限制:

  • 包含的值:GREATER_THANLESS_THANRANGE 的篩選條件包含提供的值。舉例來說,值為 2023LESS_THAN 篩選器會納入 2023 之前 (含 2023) 的所有分區。
  • 刪除分區:如果現有的目的地分區符合分區篩選器,但來源中已不再存在,系統就會從目的地中繼存放區捨棄該分區。不過,該資料分割的基礎資料檔案不會從 Cloud Storage 目的地值區刪除。
  • 單一表格限制:
    • 同一個表格中不得包含多個篩選器。
    • 您無法在同一張表格中混用不同類型的條件 (例如:GREATER_THANIN)。
  • 目標分區資料欄:GREATER_THANLESS_THANRANGE 等篩選條件必須以主要分區資料欄為目標。
  • 前置字串限制:指定的篩選條件組合不得為每個資料表解析出超過 1000 個前置字串。舉例來說,如果資料表是依 year/month/day 分區,則類似 year>2020 的篩選器必須產生少於 1000 個不重複的 year= 前置字元。

設定翻譯輸出內容

您可以為每個遷移的資料表設定專屬的 Cloud Storage 路徑和資料庫。如要這麼做,請按照下列步驟產生表格對應 YAML 檔案,以便在轉移設定中使用。

  1. DUMPER_BUCKET 中建立設定 YAML 檔案 (後置字元為 config.yaml),其中包含下列內容:

        type: object_rewriter
        relation:
        - match:
            relationRegex: ".*"
          external:
            location_expression: "'gs://MIGRATION_BUCKET/' + table.schema + '/' + table.name"
    • 請將 MIGRATION_BUCKET 改成 Cloud Storage 值區名稱,這是遷移資料表檔案的目的地。location_expression 欄位是一般運算語言 (CEL) 運算式。
  2. DUMPER_BUCKET 中建立另一個設定 YAML 檔案 (後置字串為 config.yaml),其中包含下列內容:

        type: experimental_object_rewriter
        relation:
          - match:
              schema: SOURCE_DATABASE
            outputName:
              database: null
              schema: TARGET_DATABASE
    • 請將 SOURCE_DATABASETARGET_DATABASE 替換為來源資料庫的名稱,以及 Dataproc Metastore 資料庫或 BigQuery 資料集 (視所選中繼存放區而定)。如果您要為 BigLake 中繼資料存放區設定資料庫,請確認 BigQuery 資料集存在。

    如要進一步瞭解這些設定 YAML,請參閱建立設定 YAML 檔案的指南

  3. 使用下列指令產生資料表對應 YAML 檔案:

    curl -d '{
      "tasks": {
          "string": {
            "type": "HiveQL2BigQuery_Translation",
            "translation_details": {
                "target_base_uri": "TRANSLATION_OUTPUT_BUCKET",
                "source_target_mapping": {
                  "source_spec": {
                      "base_uri": "DUMPER_BUCKET"
                  }
                },
                "target_types": ["metadata"]
            }
          }
      }
      }' \
      -H "Content-Type:application/json" \
      -H "Authorization: Bearer TOKEN" -X POST https://bigquerymigration.googleapis.com/v2alpha/projects/PROJECT_ID/locations/LOCATION/workflows

    更改下列內容:

    • TRANSLATION_OUTPUT_BUCKET:(選用) 指定用於儲存翻譯輸出內容的 Cloud Storage bucket。詳情請參閱「使用翻譯輸出內容」。
    • DUMPER_BUCKET:Cloud Storage bucket 的基本 URI,其中包含 hive-dumper-output.zip 和設定 YAML 檔案。
    • TOKEN:OAuth 權杖。您可以在指令列中,使用 gcloud auth print-access-token 指令產生這項檔案。
    • PROJECT_ID:處理翻譯作業的專案。
    • LOCATION:作業的處理位置。例如:euus
  4. 監控這項工作的狀態。完成後,系統會為 TRANSLATION_OUTPUT_BUCKET 中預先定義路徑內的資料庫中每個資料表產生對應檔案。

使用 cron 指令協調執行傾印器

您可以透過 cron 工作執行 dwh-migration-dumper 工具,自動執行增量轉移作業。自動擷取中繼資料可確保 Hadoop 的最新傾印檔可用於後續的增量轉移作業。

事前準備

使用這項自動化指令碼前,請先完成下列步驟:

  1. 完成所有 dumper 安裝必備條件,包括安裝 dwh-migration-dumper 工具和設定 IAM 權限。

  2. 安裝 Google Cloud CLI。這個指令碼會使用 gsutil 指令列工具,將傾印器輸出內容上傳至 Cloud Storage。

  3. 使用 Google Cloud 進行驗證,允許 gsutil 使用下列指令將檔案上傳至 Cloud Storage:

    gcloud auth application-default login

安排自動化動作

  1. 將下列指令碼儲存到本機檔案。這個指令碼的設計用途是透過 cron Daemon 進行設定和執行,自動擷取及上傳傾印器輸出內容:

    #!/bin/bash
    
    # Exit immediately if a command exits with a non-zero status.
    set -e
    # Treat unset variables as an error when substituting.
    set -u
    # Pipelines return the exit status of the last command to exit with a non-zero status.
    set -o pipefail
    
    # These values are used if not overridden by command-line options.
    DUMPER_EXECUTABLE="DUMPER_PATH/dwh-migration-dumper"
    GCS_BASE_PATH="gs://PATH_TO_DUMPER_OUTPUT"
    LOCAL_BASE_DIR="LOCAL_BASE_DIRECTORY_PATH"
    
    # Optional arguments for cloud environments
    DUMPER_HOST=""
    DUMPER_PORT=""
    HIVE_KERBEROS_URL=""
    HIVEQL_RPC_PROTECTION=""
    KERBEROS_AUTHENTICATION="false"
    
    # Function to display usage information
    usage() {
      echo "Usage: $0 [options]"
      echo ""
      echo "Runs the dwh-migration-dumper tool and uploads its output to provided Cloud Storage path."
      echo ""
      echo "Required Options:"
      echo "  --dumper-executable   The full path to the dumper executable."
      echo "  --gcs-base-path       The base Cloud Storage folder to upload dumper output files to. The script generates timestamped ZIP files in this folder."
      echo "  --local-base-dir      The local base directory for logs and temp files."
      echo ""
      echo "Optional Hive connection options:"
      echo "  --host              The hostname for the dumper connection."
      echo "  --port              The port number for the dumper connection."
      echo ""
      echo "To use Kerberos authentication, include the following options."
      echo "If --kerberos-authentication is specified, then --host, --port,"
      echo "--hive-kerberos-url and --hiveql-rpc-protection are all required:"
      echo ""
      echo "  --kerberos-authentication   Enable Kerberos authentication."
      echo "  --hive-kerberos-url    The Hive Kerberos URL."
      echo "  --hiveql-rpc-protection "
      echo "                            The hiveql-rpc-protection level, equal to the value of"
      echo "                            'hadoop.rpc.protection' in '/etc/hadoop/conf/core-site.xml',"
      echo "                            with one of the following values:"
      echo "                            - authentication"
      echo "                            - integrity"
      echo "                            - privacy"
      echo ""
      echo "Other Options:"
      echo "  -h, --help                  Display this help message and exit."
      exit 1
    }
    
    # This loop processes command-line options and overrides the default configuration.
    while [[ "$#" -gt 0 ]]; do
      case $1 in
          --dumper-executable)
              DUMPER_EXECUTABLE="$2"
              shift # past argument
              shift # past value
              ;;
          --gcs-base-path)
              GCS_BASE_PATH="$2"
              shift
              shift
              ;;
          --local-base-dir)
              LOCAL_BASE_DIR="$2"
              shift
              shift
              ;;
          --host)
              DUMPER_HOST="$2"
              shift
              shift
              ;;
          --port)
              DUMPER_PORT="$2"
              shift
              shift
              ;;
          --hive-kerberos-url)
              HIVE_KERBEROS_URL="$2"
              shift
              shift
              ;;
          --hiveql-rpc-protection)
              HIVEQL_RPC_PROTECTION="$2"
              shift
              shift
              ;;
          --kerberos-authentication)
              KERBEROS_AUTHENTICATION="true"
              shift
              ;;
          -h|--help)
              usage
              ;;
          *)
              echo "Unknown option: $1"
              usage
              ;;
      esac
    done
    
    # This runs AFTER parsing arguments to ensure no placeholder values are left.
    if [[ "$DUMPER_EXECUTABLE" == "DUMPER_PATH"* || "$GCS_BASE_PATH" == "gs://PATH_TO_DUMPER_OUTPUT" || "$LOCAL_BASE_DIR" == "LOCAL_BASE_DIRECTORY_PATH" ]]; then
      echo "ERROR: One or more configuration variables have not been set. Please provide them as command-line arguments or edit the script." >&2
      echo "Run with --help for more information." >&2
      exit 1
    fi
    
    # If Kerberos authentication is enabled, check for required fields.
    if [[ "$KERBEROS_AUTHENTICATION" == "true" ]]; then
      if [[ -z "$DUMPER_HOST" || -z "$DUMPER_PORT" || -z "$HIVE_KERBEROS_URL" || -z "$HIVEQL_RPC_PROTECTION" ]]; then
          echo "ERROR: If --kerberos-authentication is enabled, --host, --port, --hive-kerberos-url and --hiveql-rpc-protection must be provided." >&2
          echo "Run with --help for more information." >&2
          exit 1
      fi
    fi
    
    # Remove trailing slashes from GCS_BASE_PATH, if any.
    GCS_BASE_PATH=$(echo "${GCS_BASE_PATH}" | sed 's:/*$::')
    
    # Create unique timestamp and directories for this run
    EPOCH=$(date +%s)
    LOCAL_LOG_DIR="${LOCAL_BASE_DIR}/logs"
    mkdir -p "${LOCAL_LOG_DIR}" # Ensures the base and logs directories exist
    
    # Define the unique log and zip file path for this run
    LOG_FILE="${LOCAL_LOG_DIR}/dumper_execution_${EPOCH}.log"
    ZIP_FILE_NAME="dts-cron-dumper-output_${EPOCH}.zip"
    LOCAL_ZIP_PATH="${LOCAL_BASE_DIR}/${ZIP_FILE_NAME}"
    
    echo "Script execution started. All subsequent output will be logged to: ${LOG_FILE}"
    
    # --- Helper Functions ---
    
    log() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $@" >> "${LOG_FILE}"; }
    
    cleanup() {
      local path_to_remove="$1"
      log "Cleaning up local file/directory: ${path_to_remove}..."
      rm -rf "${path_to_remove}"
    }
    
    # This function is called when the script exits to ensure cleanup and logging happen reliably.
    handle_exit() {
      local exit_code=$?
      # Only run the failure logic if the script is exiting with an error
      if [[ ${exit_code} -ne 0 ]]; then
          log "ERROR: Script is exiting with a failure code (${exit_code})."
          local gcs_log_path_on_failure="${GCS_BASE_PATH}/logs/$(basename "${LOG_FILE}")"
          log "Uploading log file to ${gcs_log_path_on_failure} for debugging..."
          # Attempt to upload the log file on failure, but don't let this command cause the script to exit.
          gsutil cp "${LOG_FILE}" "${gcs_log_path_on_failure}" > /dev/null 2>&1 || log "WARNING: Failed to upload log file to Cloud Storage."
    
      else
          # SUCCESS PATH
          log "Script finished successfully. Now cleaning up local zip file...."
          # Clean up the local zip file ONLY on success
          cleanup "${LOCAL_ZIP_PATH}"
      fi
    
      log "*****Script End*****"
      exit ${exit_code}
    }
    
    # Trap the EXIT signal to run the handle_exit function, ensuring cleanup always happens.
    trap handle_exit EXIT
    
    # Validates the dumper log file based on a strict set of rules.
    validate_dumper_output() {
      local log_file_to_check="$1"
    
      # Check for the specific success message from the dumper tool.
      if grep -q "Dumper execution: SUCCEEDED" "${log_file_to_check}"; then
          log "Validation Successful: Found 'Dumper execution: SUCCEEDED' message."
          return 0 # Success
      else
          log "ERROR: Validation failed. The 'Dumper execution: SUCCEEDED' message was not found."
          return 1 # Failure
      fi
    }
    
    # --- Main Script Logic ---
    
    log "*****Script Start*****"
    log "Dumper Executable: ${DUMPER_EXECUTABLE}"
    log "Cloud Storage Base Path: ${GCS_BASE_PATH}"
    log "Local Base Directory: ${LOCAL_BASE_DIR}"
    
    # Use an array to build the command safely
    dumper_command_args=(
      "--connector" "hiveql"
      "--output" "${LOCAL_ZIP_PATH}"
    )
    
    # Add optional arguments if they are provided
    if [[ -n "${DUMPER_HOST}" ]]; then
    dumper_command_args+=("--host" "${DUMPER_HOST}")
    log "Using Host: ${DUMPER_HOST}"
    fi
    if [[ -n "${DUMPER_PORT}" ]]; then
    dumper_command_args+=("--port" "${DUMPER_PORT}")
    log "Using Port: ${DUMPER_PORT}"
    fi
    if [[ -n "${HIVE_KERBEROS_URL}" ]]; then
    dumper_command_args+=("--hive-kerberos-url" "${HIVE_KERBEROS_URL}")
    log "Using Hive Kerberos URL: ${HIVE_KERBEROS_URL}"
    fi
    if [[ -n "${HIVEQL_RPC_PROTECTION}" ]]; then
    dumper_command_args+=("-Dhiveql.rpc.protection=${HIVEQL_RPC_PROTECTION}")
    log "Using HiveQL RPC Protection: ${HIVEQL_RPC_PROTECTION}"
    fi
    
    log "Starting dumper tool execution..."
    log "COMMAND: JAVA_OPTS=\"-Djavax.security.auth.useSubjectCredsOnly=false\" ${DUMPER_EXECUTABLE} ${dumper_command_args[*]}"
    
    JAVA_OPTS="-Djavax.security.auth.useSubjectCredsOnly=false" "${DUMPER_EXECUTABLE}" "${dumper_command_args[@]}" >> "${LOG_FILE}" 2>&1
    
    log "Dumper process finished."
    
    # Validate the output from the dumper execution for success or failure.
    validate_dumper_output "${LOG_FILE}"
    
    # Upload the ZIP file to Cloud Storage
    gcs_zip_path="${GCS_BASE_PATH}/${ZIP_FILE_NAME}"
    log "Uploading ${LOCAL_ZIP_PATH} to ${gcs_zip_path}..."
    
    if [ ! -f "${LOCAL_ZIP_PATH}" ]; then
      log "ERROR: Expected ZIP file ${LOCAL_ZIP_PATH} not found after dumper execution."
      # The script will exit here with an error code, and the trap will run.
      exit 1
    fi
    
    gsutil cp "${LOCAL_ZIP_PATH}" "${gcs_zip_path}" >> "${LOG_FILE}" 2>&1
    log "Upload to Cloud Storage successful."
    
    # The script will now exit with code 0. The trap will call cleanup and log the script end.
  2. 執行下列指令,讓指令碼變成可執行:

    chmod +x PATH_TO_SCRIPT
  3. 使用 crontab 排定指令碼執行時間,並將變數替換為適合您工作的值。新增項目來排定工作。 下列範例會在每天凌晨 2:30 執行指令碼:

    如果您在可直接存取 Apache Hive 的主機上執行,且不需要 Kerberos 驗證,請使用下列指令:

    不使用 Kerberos 驗證

    # Run the Hive dumper daily at 2:30 AM for incremental BigQuery transfer.
    30 2 * * * PATH_TO_SCRIPT 
    --dumper-executable PATH_TO_DUMPER_EXECUTABLE
    --gcs-base-path GCS_PATH_TO_UPLOAD_DUMPER_OUTPUT
    --local-base-dir LOCAL_PATH_TO_SAVE_INTERMEDIARY_FILES

    如果 Apache Hive 執行個體需要 Kerberos 驗證,請使用下列指令:

    使用 Kerberos 驗證

    # Run the Hive dumper daily at 2:30 AM for incremental BigQuery transfer with Kerberos authentication.
    30 2 * * * PATH_TO_SCRIPT 
    --dumper-executable PATH_TO_DUMPER_EXECUTABLE
    --gcs-base-path GCS_PATH_TO_UPLOAD_DUMPER_OUTPUT
    --local-base-dir LOCAL_PATH_TO_SAVE_INTERMEDIARY_FILES
    --kerberos-authentication
    --host HIVE_HOST
    --port HIVE_PORT
    --hive-kerberos-url HIVE_KERBEROS_URL
    --hiveql-rpc-protection HIVEQL_RPC_PROTECTION

  4. 建立移轉作業時,請確保 table_metadata_path 欄位設為您為 GCS_PATH_TO_UPLOAD_DUMPER_OUTPUT 設定的相同 Cloud Storage 路徑。這是包含傾印器輸出 ZIP 檔案的路徑。

排程注意事項

為避免資料過時,請務必在排定的轉移作業開始前,準備好中繼資料傾印。請視情況設定 cron 工作頻率。

建議您手動執行幾次指令碼,判斷傾印工具產生輸出內容的平均時間。請利用這個時間點設定cron排程,確保排程安全地在 DTS 移轉作業執行前完成,並確保資料是最新狀態。

監控及查看轉移狀態

您可以監控個別資料表的資源層級轉移作業,追蹤進度、查看詳細的錯誤資訊,以及查詢正在遷移的特定資源狀態。

如要查看資源的進度和狀態,請選取下列其中一個選項:

控制台

  1. 前往 Google Cloud 控制台的「資料移轉」頁面。

    前往「資料轉移」頁面

  2. 從清單中點選移轉設定。

  3. 在「Transfer details」(移轉作業詳細資料) 頁面中,按一下「Tables transferred」(已移轉的資料表) 分頁標籤。

  4. 查看要移轉的資源清單。您可以查看下列詳細資料:

    • 上次移轉狀態:資源的目前狀態,以最新資源移轉作業為準,包括完成進度。
    • 資料表名稱:待移轉資源的名稱。按一下資源名稱,即可查看資源的詳細資料。
    • 最近一次執行:上次更新資源的轉移作業。
    • 狀態摘要:精細的進度指標,或轉移失敗時的錯誤訊息。
    • 上次成功執行:上次成功移轉資源的執行作業。

使用篩選列依名稱搜尋特定資源,或依目前狀態篩選,例如「傳輸失敗」。「資料表名稱」篩選器支援萬用字元比對 (例如使用 *),但其他篩選器欄位不支援萬用字元比對。

API

您可以使用 BigQuery 資料移轉服務 API 查詢移轉資源的狀態。

列出所有資源及其狀態

如要列出所有資源及其狀態,請使用 projects.locations.transferConfigs.transferResources.list 方法

使用下列資訊執行 API 要求:

  GET https://bigquerydatatransfer.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/transferConfigs/CONFIG_ID/transferResources
  Example Response (abridged) (JSON):
  {
    "transferResources": [
      {
        "name": "projects/.../transferResources/table1",
        "latestStatusDetail": {
          "state": "RESOURCE_TRANSFER_SUCCEEDED",
          "completedPercentage": 100.0
        },
        "updateTime": "2026-02-03T22:42:06Z"
      }
    ]
  }
  

curl 指令:

  curl -X GET 
"https://bigquerydatatransfer.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/transferConfigs/CONFIG_ID/transferResources"
-H "Authorization: Bearer $(gcloud auth print-access-token)"
-H "Accept: application/json"

您可以依資源名稱或狀態篩選結果。舉例來說,如要找出所有失敗的轉移作業,請在要求網址中加入 ?filter=latest_status_detail.state="RESOURCE_TRANSFER_FAILED"

更改下列內容:

  • CONFIG_ID:轉移設定的 ID。
  • LOCATION:建立轉移設定的位置。
  • PROJECT_ID:執行轉移作業的 Google Cloud 專案 ID。

取得特定資源

如要取得特定資料表或分區的狀態,請使用 projects.locations.transferConfigs.transferResources.get 方法

使用下列資訊執行 API 要求:

  GET https://bigquerydatatransfer.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/transferConfigs/CONFIG_ID/transferResources/RESOURCE_ID
  

curl 指令:

  curl -X GET 
"https://bigquerydatatransfer.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/transferConfigs/CONFIG_ID/transferResources/RESOURCE_ID"
-H "Authorization: Bearer $(gcloud auth print-access-token)"
-H "Accept: application/json"

更改下列內容:

  • CONFIG_ID:轉移設定的 ID。
  • LOCATION:建立轉移設定的位置。
  • PROJECT_ID:執行轉移作業的 Google Cloud 專案 ID。
  • RESOURCE_ID:資源的 ID,例如資料表名稱。