Apache Iceberg 代管資料表

Apache Iceberg 代管資料表 (舊稱 BigQuery 中的 Apache Iceberg 專用 BigLake 資料表) 是在 Google Cloud上建構開放格式湖倉的基礎。Iceberg 代管資料表提供與標準 BigQuery 資料表相同的全代管體驗,但資料會儲存在客戶擁有的儲存空間 bucket。Iceberg 代管資料表支援開放式 Iceberg 資料表格式,可與開放原始碼和第三方運算引擎更有效地互通,並使用單一資料副本。

Iceberg 代管資料表支援下列功能:

架構

Iceberg 代管資料表可讓您在自己的雲端 bucket 中,輕鬆管理 BigQuery 資源。您可以在這些資料表上使用 BigQuery 和開放原始碼運算引擎,不必將資料移出您控管的 bucket。您必須先設定 Cloud Storage bucket,才能開始使用 Iceberg 代管資料表。

使用 Iceberg 代管資料表會對 bucket 造成下列影響:

  • BigQuery 會在 bucket 中建立新的資料檔案,以回應寫入要求和背景儲存空間最佳化作業,例如 DML 陳述式和串流。
  • 系統會對 bucket 中的資料檔案執行自動壓縮和分群。時間旅行期間過後,資料檔案會進行垃圾收集。不過,如果資料表遭到刪除,系統不會對相關聯的資料檔案進行垃圾收集。詳情請參閱「儲存空間最佳化」。

建立 Iceberg 代管資料表的方式與建立 BigQuery 資料表類似。由於資料是以開放格式儲存在 Cloud Storage,因此您必須執行下列操作:

  • 指定 Cloud 資源連結,並使用 WITH CONNECTION 設定 BigQuery 存取 Cloud Storage 的連線憑證。
  • 使用 file_format = PARQUET 陳述式,將資料儲存庫的檔案格式指定為 PARQUET。
  • 使用 table_format = ICEBERG 陳述式,將開放原始碼中繼資料資料表格式指定為 ICEBERG。

最佳做法

如果直接在 BigQuery 以外的地方變更或新增檔案至 bucket,可能會導致資料遺失或發生無法復原的錯誤。下表說明可能的情況:

作業 後果 預防
在 BigQuery 外部,將新檔案新增至 bucket。 資料遺失:BigQuery 不會追蹤在 BigQuery 外部新增的檔案或物件。未追蹤的檔案會由背景垃圾收集程序刪除。 只能透過 BigQuery 新增資料。這樣一來,BigQuery 就能追蹤檔案,並防止檔案遭到垃圾收集。
為避免意外新增和資料遺失,建議您限制外部工具對含有 Iceberg 代管資料表的 bucket 寫入權限。
在非空白前置字串中建立新的 Iceberg 代管資料表。 資料遺失:BigQuery 不會追蹤現有資料,因此這些檔案會視為未追蹤,並由背景垃圾收集程序刪除。 請只在空白前置字串中建立新的 Iceberg 代管資料表。
修改或取代 Iceberg 代管資料表的資料檔案。 資料遺失:如果外部修改或替換,資料表會無法通過一致性檢查,且無法讀取。對資料表執行的查詢會失敗。
您無法自行復原。請與支援團隊聯絡,尋求資料復原協助。
只能透過 BigQuery 修改資料。這樣一來,BigQuery 就能追蹤檔案,並防止檔案遭到垃圾收集。
為避免意外新增和資料遺失,建議您限制外部工具對含有 Iceberg 代管資料表的 bucket 寫入權限。
在相同或重疊的 URI 上建立兩個 Iceberg 代管資料表。 資料遺失:BigQuery 不會橋接 Iceberg 代管資料表的相同 URI 執行個體。每個資料表的背景垃圾收集程序會將對應資料表的檔案視為未追蹤,並將其刪除,導致資料遺失。 每個 Iceberg 代管資料表都應使用專屬 URI。

Cloud Storage bucket 設定最佳做法

Cloud Storage bucket 的設定及其與 BigQuery 的連線,會直接影響 Iceberg 代管資料表的效能、成本、資料完整性、安全性和治理。以下是這項設定的最佳做法:

  • 請選取能清楚指出 bucket 僅用於 Iceberg 代管資料表的名稱。

  • 選擇與 BigQuery 資料集位於相同區域的單一區域 Cloud Storage bucket。這種協調方式可避免資料移轉費用,進而提升效能並降低成本。

  • 根據預設,Cloud Storage 會將資料儲存在 Standard Storage 級別,提供足夠的效能。如要盡可能降低資料儲存費用,可以啟用 Autoclass,自動管理儲存空間級別轉換。Autoclass 會從 Standard Storage 開始,將未存取的物件移至存取頻率較低的級別,以降低儲存費用。再次讀取物件時,物件會移回 Standard 級別。

  • 啟用統一 bucket 層級存取權和公開存取預防措施。

  • 確認必要角色已指派給正確的使用者和服務帳戶。

  • 為避免 Cloud Storage bucket 中的資料意外刪除或損毀,請限制組織中多數使用者的寫入和刪除權限。方法是設定值區權限政策,並加入條件,拒絕所有使用者 (指定使用者除外) 的 PUT 和 DELETE 要求。

  • 套用 Google 代管或客戶自行管理的加密金鑰,進一步保護機密資料。

  • 啟用稽核記錄,確保作業透明度、排解問題及監控資料存取。

  • 保留預設的虛刪除政策 (保留 7 天),防止意外刪除。不過,如果發現資料遭到刪除,請與支援團隊聯絡,不要手動還原物件,因為在 BigQuery 外部新增或修改的物件不會由 BigQuery 中繼資料追蹤。

  • 系統會自動啟用自動調整檔案大小、自動分群和垃圾收集功能,協助您最佳化檔案效能和成本。

  • 請避免使用下列 Cloud Storage 功能,因為 Iceberg 代管資料表不支援這些功能:

您可以使用下列指令建立 bucket,藉此實作這些最佳做法:

gcloud storage buckets create gs://BUCKET_NAME \
    --project=PROJECT_ID \
    --location=LOCATION \
    --enable-autoclass \
    --public-access-prevention \
    --uniform-bucket-level-access

更改下列內容:

  • BUCKET_NAME:新 bucket 的名稱
  • PROJECT_ID:專案 ID
  • LOCATION:新 bucket 的位置

Iceberg 代管資料表工作流程

以下各節說明如何建立、載入、管理及查詢 Iceberg 代管資料表。

事前準備

建立及使用 Iceberg 代管資料表前,請務必設定Cloud 資源連結,連至儲存空間 bucket。連線必須具備儲存空間 bucket 的寫入權限,如以下「必要角色」一節所述。如要進一步瞭解連線所需的角色和權限,請參閱「管理連線」。

必要的角色

如要取得所需權限,讓 BigQuery 管理專案中的資料表,請要求管理員授予您下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

這些預先定義的角色具備所需權限,可讓 BigQuery 管理專案中的資料表。如要查看確切的必要權限,請展開「Required permissions」(必要權限) 部分:

所需權限

必須具備下列權限,BigQuery 才能管理專案中的資料表:

  • 全部:
    • 專案的 bigquery.connections.delegate
    • 專案的 bigquery.jobs.create
    • 專案的 bigquery.readsessions.create
    • 專案的 bigquery.tables.create
    • 專案的 bigquery.tables.get
    • 專案的 bigquery.tables.getData
    • bucket 的 storage.buckets.get
    • storage.objects.create 在 bucket
    • storage.objects.delete 在 bucket
    • storage.objects.get 在 bucket
    • storage.objects.list 在 bucket

您或許還可透過自訂角色或其他預先定義的角色取得這些權限。

建立 Iceberg 代管資料表

如要建立 Iceberg 代管資料表,請選取下列其中一種方法:

SQL

CREATE TABLE [PROJECT_ID.]DATASET_ID.TABLE_NAME (
COLUMN DATA_TYPE[, ...]
)
CLUSTER BY CLUSTER_COLUMN_LIST
WITH CONNECTION {CONNECTION_NAME | DEFAULT}
OPTIONS (
file_format = 'PARQUET',
table_format = 'ICEBERG',
storage_uri = 'STORAGE_URI');

更改下列內容:

  • PROJECT_ID:包含資料集的專案。如未定義,指令會假設使用預設專案。
  • DATASET_ID:現有資料集。
  • TABLE_NAME:要建立的資料表名稱。
  • DATA_TYPE:資料欄所含資訊的資料類型。
  • CLUSTER_COLUMN_LIST (選用):以半形逗號分隔的清單,最多包含四個資料欄。必須是頂層、非重複的資料欄。
  • CONNECTION_NAME:連線名稱。例如:myproject.us.myconnection。如要使用預設連線,請指定 DEFAULT,而非連線名稱。
  • STORAGE_URI:完整的 Cloud Storage URI。例如:gs://mybucket/table。

bq

bq --project_id=PROJECT_ID mk \
    --table \
    --file_format=PARQUET \
    --table_format=ICEBERG \
    --connection_id=CONNECTION_NAME \
    --storage_uri=STORAGE_URI \
    --schema=COLUMN_NAME:DATA_TYPE[, ...] \
    --clustering_fields=CLUSTER_COLUMN_LIST \
    DATASET_ID.MANAGED_TABLE_NAME

更改下列內容:

  • PROJECT_ID:包含資料集的專案。如未定義,指令會假設使用預設專案。
  • CONNECTION_NAME:連線名稱。例如:myproject.us.myconnection。
  • STORAGE_URI:完整的 Cloud Storage URI。例如:gs://mybucket/table。
  • COLUMN_NAME:資料欄名稱。
  • DATA_TYPE:資料欄所含資訊的資料類型。
  • CLUSTER_COLUMN_LIST (選用):以半形逗號分隔的清單,最多包含四個資料欄。必須是頂層、非重複的資料欄。
  • DATASET_ID:現有資料集的 ID。
  • MANAGED_TABLE_NAME:要建立的資料表名稱。

API

使用定義的資料表資源呼叫 tables.insert 方法,如下所示:

{
"tableReference": {
  "tableId": "TABLE_NAME"
},
"biglakeConfiguration": {
  "connectionId": "CONNECTION_NAME",
  "fileFormat": "PARQUET",
  "tableFormat": "ICEBERG",
  "storageUri": "STORAGE_URI"
},
"schema": {
  "fields": [
    {
      "name": "COLUMN_NAME",
      "type": "DATA_TYPE"
    }
    [, ...]
  ]
}
}

更改下列內容:

  • TABLE_NAME:要建立的資料表名稱。
  • CONNECTION_NAME:連線名稱。例如:myproject.us.myconnection。
  • STORAGE_URI:完整的 Cloud Storage URI。也支援萬用字元。例如:gs://mybucket/table。
  • COLUMN_NAME:資料欄名稱。
  • DATA_TYPE:資料欄所含資訊的資料類型。

將資料匯入 Iceberg 代管資料表

以下各節說明如何將各種資料表格式的資料,匯入 Iceberg 代管資料表。

從平面檔載入標準資料

Iceberg 代管資料表會使用 BigQuery 載入工作,將外部檔案載入 Iceberg 代管資料表。如果您已有 Iceberg 代管資料表,請按照 bq load CLI 指南或 LOAD SQL 指南載入外部資料。載入資料後,新的 Parquet 檔案會寫入 STORAGE_URI/data 資料夾。

如果按照上述操作說明,但沒有現成的 Iceberg 代管資料表,系統會改為建立 BigQuery 資料表。

請參閱下列範例,瞭解如何使用特定工具將批次資料載入 Iceberg 代管資料表:

SQL

LOAD DATA INTO MANAGED_TABLE_NAME
FROM FILES (
uris=['STORAGE_URI'],
format='FILE_FORMAT');

更改下列內容:

  • MANAGED_TABLE_NAME:現有 Iceberg 代管資料表的名稱。
  • STORAGE_URI:完整 Cloud Storage URI,或以半形逗號分隔的 URI 清單。也支援萬用字元。例如:gs://mybucket/table。
  • FILE_FORMAT:來源資料表格式。如要瞭解支援的格式,請參閱 load_option_list 的 format 列。

bq

bq load \
  --source_format=FILE_FORMAT \
  MANAGED_TABLE \
  STORAGE_URI

更改下列內容:

  • FILE_FORMAT:來源資料表格式。如要瞭解支援的格式,請參閱 load_option_list 的 format 列。
  • MANAGED_TABLE_NAME:現有 Iceberg 代管資料表的名稱。
  • STORAGE_URI:完整 Cloud Storage URI,或以半形逗號分隔的 URI 清單。也支援萬用字元。例如:gs://mybucket/table。

從 Apache Hive 分區檔案標準載入

您可以使用標準 BigQuery 載入工作,將 Hive 分區檔案載入 Iceberg 代管資料表。詳情請參閱「載入外部分區資料」。

從 Pub/Sub 載入串流資料

您可以使用 Pub/Sub BigQuery 訂閱項目,將串流資料載入 Iceberg 代管資料表。

使用持續查詢載入串流資料

您可以使用 BigQuery 持續查詢搭配 INSERT DML 陳述式,持續處理 BigQuery 的串流資料,並寫入 Iceberg 代管資料表。這樣一來,您就能在開放格式的湖倉中,即時執行反向 ETL、資料充實和篩選作業。

執行持續查詢前,請確認目標 Iceberg 代管資料表存在,且使用者或服務帳戶具備資料表、其 Google Cloud 資源連線和基礎 Cloud Storage bucket 的必要權限。

如需設定操作說明和 SQL 範例,請參閱「將資料寫入 BigQuery 或 Apache Iceberg 代管資料表」。

從 Iceberg 代管資料表匯出資料

以下各節說明如何將 Iceberg 代管資料表中的資料,匯出為各種資料表格式。

將資料匯出為平面格式

如要將 Iceberg 代管資料表匯出為平面格式,請使用 EXPORT DATA 陳述式,並選取目的地格式。詳情請參閱「匯出資料」。

建立 Iceberg 代管資料表中繼資料快照

如要建立 Iceberg 代管資料表中繼資料快照,請按照下列步驟操作:

  1. 使用 EXPORT TABLE METADATA SQL 陳述式,將中繼資料匯出為 Iceberg V2 格式。

  2. 選用:排定 Iceberg 中繼資料快照重新整理作業。如要根據設定的時間間隔重新整理 Iceberg 中繼資料快照,請使用排定的查詢。

  3. 選用:為專案啟用中繼資料自動重新整理功能,在每次資料表變動時,自動更新 Iceberg 資料表中繼資料快照。如要啟用中繼資料自動重新整理功能,請與 bigquery-tables-for-apache-iceberg-help@google.com 聯絡。每次重新整理作業都會產生 EXPORT METADATA 費用。

下列範例使用 DDL 陳述式 EXPORT TABLE METADATA FROM mydataset.test 建立名為 My Scheduled Snapshot Refresh Query 的排定查詢。DDL 陳述式每 24 小時執行一次。

bq query \
    --use_legacy_sql=false \
    --display_name='My Scheduled Snapshot Refresh Query' \
    --schedule='every 24 hours' \
    'EXPORT TABLE METADATA FROM mydataset.test'

查看 Iceberg 代管資料表中繼資料快照

重新整理 Iceberg 代管資料表中繼資料快照後,您可以在最初建立 Iceberg 代管資料表的 Cloud Storage URI 中找到該快照。/data 資料夾包含 Parquet 檔案資料 shard,/metadata 資料夾則包含 Iceberg 代管資料表中繼資料快照。

SELECT
  table_name,
  REGEXP_EXTRACT(ddl, r"storage_uri\s*=\s*\"([^\"]+)\"") AS storage_uri
FROM
  `mydataset`.INFORMATION_SCHEMA.TABLES;

請注意,mydataset 和 table_name 是實際資料集和資料表的預留位置。

使用 Spark 讀取 Iceberg 代管資料表

下列範例會設定環境,以便搭配使用 Spark SQL 和 Spark,然後執行查詢,從指定的 Iceberg 代管資料表擷取資料。

spark-sql \
  --packages org.apache.iceberg:iceberg-spark-runtime-ICEBERG_VERSION_NUMBER \
  --conf spark.sql.catalog.CATALOG_NAME=org.apache.iceberg.spark.SparkCatalog \
  --conf spark.sql.catalog.CATALOG_NAME.type=hadoop \
  --conf spark.sql.catalog.CATALOG_NAME.warehouse='BUCKET_PATH' \

# Query the table
SELECT * FROM CATALOG_NAME.FOLDER_NAME;

更改下列內容:

  • ICEBERG_VERSION_NUMBER:目前的執行階段版本。請前往 Iceberg 版本下載最新版本。
  • CATALOG_NAME:參照 Iceberg 代管資料表的目錄。
  • BUCKET_PATH:資料表檔案所在 bucket 的路徑。 例如:gs://mybucket/。
  • FOLDER_NAME:包含資料表檔案的資料夾。例如:myfolder。

修改 Iceberg 代管資料表

如要修改 Iceberg 代管資料表,請按照「修改資料表結構定義」中的步驟操作。

使用多陳述式交易

您可以對 Iceberg 代管資料表使用多陳述式交易,方法與標準 BigQuery 資料表相同。多重陳述式交易通常用於同時對多個資料表執行異動,或對單一資料表執行多個階段的異動。多陳述式交易可保證 ACID 屬性,並支援快照隔離。

適用標準多陳述式交易限制。

使用分區

您可以對 Iceberg 代管資料表使用資料表分區,方法與標準 BigQuery 資料表類似。您可以指定分區資料欄來區隔資料表。Iceberg 代管資料表支援下列資料欄類型:

  • DATE
  • DATETIME
  • TIMESTAMP

依 DATE、DATETIME 或 TIMESTAMP 資料欄分區資料表,稱為「時間單位資料欄分區」。您可以選擇分區的精細程度為小時、日、月或年。

Iceberg 代管資料表也支援分群,以及合併分群和分區資料表。

分區限制

建立分區 Iceberg 代管資料表

如要建立分區 Iceberg 代管資料表,請按照操作說明建立標準 Iceberg 代管資料表,並依據環境加入下列其中一項:

您可以按照與標準 BigQuery 資料表相同的方式,設定及更新分區到期時間。過期的分區會在時間回溯期結束後,由垃圾收集機制處理。如果將資料新增至已過期的分區,資料會立即過期。

修改及查詢分區 Iceberg 代管資料表

分區 Iceberg 代管資料表的 BigQuery 資料操縱語言 (DML) 陳述式和查詢,與標準 Iceberg 代管資料表相同。BigQuery 會自動將工作範圍限定在正確的分區,類似於 Iceberg 隱藏分區。此外,您新增至資料表的任何新資料都會自動分區。

您也可以使用其他引擎查詢分區 Iceberg 代管資料表,方法與標準 Iceberg 代管資料表相同。建議啟用中繼資料快照,以獲得最佳體驗。

為強化安全性,Iceberg 代管資料表的分區資訊會與資料路徑分離,並完全由中繼資料層管理。

定價

Iceberg 代管資料表的定價包含儲存空間、儲存空間最佳化、查詢和工作。

儲存空間

Iceberg 代管資料表會將所有資料儲存在 Cloud Storage。系統會根據所有儲存的資料 (包括歷來資料表資料) 向您收費。您可能也需要支付 Cloud Storage 資料處理和移轉費用。透過 BigQuery 或 BigQuery Storage API 處理的作業,可能可以免除部分 Cloud Storage 作業費用。BigQuery 不會收取專屬的儲存費用。詳情請參閱 Cloud Storage 定價。

儲存空間最佳化

Iceberg 代管資料表會自動執行資料表管理作業,包括壓縮、分群、垃圾回收,以及 BigQuery 中繼資料生成/重新整理,以最佳化查詢效能並降低儲存成本。資料表管理的運算資源用量,會以資料運算單元 (DCU) 為單位,按時間累計,以秒為單位。詳情請參閱「Iceberg 代管資料表定價」。

透過 Storage Write API 串流時執行的資料匯出作業,會計入 Storage Write API 定價,不會視為背景維護作業收費。詳情請參閱「資料擷取定價」。

如要查看這些背景作業的記錄和運算用量,請查詢 INFORMATION_SCHEMA.JOBS 檢視表。如需查詢範例,請參閱下列內容:

查詢和工作

與 BigQuery 資料表類似,如果您使用 BigQuery 隨選計價模式,則須支付查詢和讀取位元組 (每 TiB) 的費用;如果您使用 BigQuery 運算資源計價模式,則須支付運算單元消耗量 (每運算單元時數) 的費用。

BigQuery 定價也適用於 BigQuery Storage Read API 和 Storage Write API。

載入和匯出作業 (例如 EXPORT METADATA) 會使用企業版即付即用運算單元。這與 BigQuery 資料表不同,後者不會對這些作業收費。如果 PIPELINE 預留項目有 Enterprise 或 Enterprise Plus 運算單元,載入和匯出作業會優先使用這些預留項目運算單元。

限制

Iceberg 代管資料表有下列限制:

  • Iceberg 代管資料表不支援重新命名作業或 ALTER TABLE RENAME TO 陳述式。
  • Iceberg 代管資料表不支援資料表複製或 CREATE TABLE COPY 陳述式。
  • Iceberg 代管資料表不支援資料表複製或 CREATE TABLE CLONE 陳述式。
  • Iceberg 代管資料表不支援資料表快照或 CREATE SNAPSHOT TABLE 陳述式。
  • Iceberg 代管資料表不支援下列資料表結構定義:
    • 結構定義空白
    • 包含 BIGNUMERIC、INTERVAL、JSON、RANGE 或 GEOGRAPHY 資料類型的結構定義。
    • 具有欄位定序的結構定義。
    • 含有預設值運算式的結構定義。
  • Iceberg 代管資料表不支援下列結構定義演進案例:
    • NUMERIC 到 FLOAT 類型強制轉型
    • INT 到 FLOAT 類型強制轉型
    • 使用 SQL DDL 陳述式,將新的巢狀欄位新增至現有的 RECORD 資料欄
  • 透過控制台或 API 查詢 Iceberg 代管資料表時,儲存空間大小會顯示為 0 位元組。
  • Iceberg 代管資料表不支援 materialized view。
  • Iceberg 代管資料表不支援授權檢視表,但支援資料欄層級存取控管。
  • Iceberg 代管資料表不支援代管災難復原
  • Iceberg 代管資料表不支援資料列層級安全性。
  • Iceberg 代管資料表不支援安全失敗期。
  • Iceberg 代管資料表不支援擷取工作。
  • INFORMATION_SCHEMA.TABLE_STORAGE 檢視表不含 Iceberg 代管資料表。
  • Iceberg 代管資料表不支援做為查詢結果目的地。您可以改用 CREATE TABLE 陳述式和 AS query_statement 引數,建立資料表做為查詢結果目的地。
  • CREATE OR REPLACE 不支援將標準資料表替換為 Iceberg 代管資料表,或將 Iceberg 代管資料表替換為標準資料表。
  • 批次載入和 LOAD DATA 陳述式僅支援將資料附加至現有的 Iceberg 代管資料表。
  • 批次載入和 LOAD DATA 陳述式不支援結構定義更新。
  • TRUNCATE TABLE 不支援 Iceberg 代管資料表。有兩種替代方案:
  • APPENDS 資料表值函式 (TVF) 不支援 Iceberg 代管資料表。
  • Iceberg 中繼資料可能不含過去 90 分鐘內,由 Storage Write API 串流至 BigQuery 的資料。
  • 使用 tabledata.list 的記錄式分頁存取不支援 Iceberg 代管資料表。
  • 每個 Iceberg 代管資料表只能同時執行一個變動 DML 陳述式 (UPDATE、DELETE 和 MERGE)。其他變更 DML 陳述式會排入佇列。