使用 Spark 和 Lakehouse 執行階段目錄建立 Lakehouse

湖倉架構結合了資料湖泊的彈性,以及資料倉儲的資料管理功能。本文說明如何在 Google Cloud上設定湖倉。您將使用 Apache Iceberg 做為資料表格式、Managed Service for Apache Spark 進行處理,並使用 Lakehouse 執行階段目錄 Iceberg REST 目錄,統一管理中繼資料。

這個架構使用 Iceberg 等開放資料表格式,為 Cloud Storage 中的資料新增資料倉儲功能,例如交易和結構定義演進。這種做法可為資料建立單一事實來源,供各種引擎存取。

本文說明在 Lakehouse 執行階段目錄中建立的目錄。如要透過 Lakehouse 執行階段目錄聯合目錄,查詢由 AWS Glue Data Catalog、Databricks Unity Catalog 或 Snowflake Horizon Catalog 管理的 Iceberg 資料表,請參閱「使用 Spark 查詢聯合目錄」。

這張圖表顯示湖倉架構的元件,包括 Managed Service for Apache Spark、Cloud Storage 和 Lakehouse REST 目錄。
湖倉架構圖。

事前準備

  1. 登入 Google Cloud 帳戶。如果您未曾使用過 Google Cloud,歡迎 建立帳戶,親自體驗實際使用我們產品的成效。新客戶還能獲得價值 $300 美元的免費抵免額,用於執行、測試及部署工作負載。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that you have the permissions required to complete this guide.

  4. Verify that billing is enabled for your Google Cloud project.

  5. Enable the Dataproc, BigLake, BigQuery, and Cloud Storage APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  6. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  7. Verify that you have the permissions required to complete this guide.

  8. Verify that billing is enabled for your Google Cloud project.

  9. Enable the Dataproc, BigLake, BigQuery, and Cloud Storage APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  10. 建立 Cloud Storage bucket,用於儲存 Iceberg 資料。
  11. 在 Lakehouse 執行階段目錄中建立目錄,並指向 bucket。建議使用多值區目錄。

必要的角色

如要執行本頁面的範例,您必須具備特定 Identity and Access Management (IAM) 角色。視機構政策而定,這些角色可能已獲授權。如要查看角色授權,請參閱「是否需要授予角色?」一文。

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

您需要的角色取決於工作負載的執行方式。 Managed Service for Apache Spark 叢集和 Managed Service for Apache Spark 無伺服器執行階段 2.3 及更早版本,會以服務帳戶的身分執行工作負載。Managed Service for Apache Spark 無伺服器執行階段 3.0 和後續版本預設會使用使用者憑證 (EUC) 執行工作負載,因此您要將資料存取角色授予使用者帳戶,而非服務帳戶。如果您為 3.0 以上的執行階段指定自訂服務帳戶,工作負載會使用服務帳戶憑證執行。詳情請參閱「無伺服器部署作業角色」。

使用者角色

如要取得建立 Managed Service for Apache Spark 叢集、提交批次工作負載或建立互動式工作階段所需的權限,請要求管理員授予您下列 IAM 角色:

  • 使用叢集或無伺服器執行階段 2.3 以下版本:
    • 專案的 Dataproc 編輯者 (roles/dataproc.editor)
    • Compute Engine 預設服務帳戶或自訂服務帳戶的「服務帳戶使用者」 (roles/iam.serviceAccountUser)
  • 使用無伺服器執行階段 3.0 以上版本:專案的 Dataproc Serverless 編輯者 (roles/dataproc.serverlessEditor)
  • 在無伺服器執行階段 3.0 以上版本使用服務帳戶憑證:自訂服務帳戶的服務帳戶使用者 (roles/iam.serviceAccountUser)

如果您使用 Managed Service for Apache Spark 無伺服器執行階段 3.0 以上版本,並搭配使用者憑證 (預設),則還需要下列資料存取角色:

如要取得所需權限,以便使用使用者憑證讀取及寫入目錄中的資料表,請要求管理員授予您下列 IAM 角色:

  • 在憑證販售模式中讀取及寫入資料表資料:在包含目錄的專案中,具備 BigLake 編輯者 (roles/biglake.editor) 角色
  • 在非憑證臨時配發模式下,管理目錄資源及寫入資料表資料:

服務帳戶角色

將下列角色授予執行工作負載的服務帳戶。如果工作負載使用服務帳戶憑證執行,Managed Service for Apache Spark 無伺服器執行階段 3.0 以上版本才需要這些角色。

為確保 Compute Engine 預設服務帳戶或自訂服務帳戶具備執行 Managed Service for Apache Spark 工作,以及讀取及寫入目錄中資料表所需的權限,請管理員將下列 IAM 角色授予 Compute Engine 預設服務帳戶或自訂服務帳戶:

  • 在叢集或無伺服器執行階段 2.3 或更早版本上執行 Managed Service for Apache Spark 工作: 專案中的 Dataproc Worker (roles/dataproc.worker)
  • 在無伺服器執行階段 3.0 以上版本執行 Managed Service for Apache Spark 工作:
  • 在憑證販售模式下讀取及寫入資料表資料: 目錄所屬專案的 BigLake 編輯器 (roles/biglake.editor)
  • 在非憑證臨時配發模式下,管理目錄資源及寫入資料表資料:

設定 Managed Service for Apache Spark 並建立 Spark 工作階段

設定 Managed Service for Apache Spark 叢集、Managed Service for Apache Spark 無伺服器批次工作負載,或 Managed Service for Apache Spark 無伺服器互動式工作階段,以使用 Lakehouse 執行階段目錄 Iceberg REST 目錄。這三種方法都支援 dataproc.lakehouse.catalog.CATALOG_NAME 簡化設定屬性 (建議),可讓 Managed Service for Apache Spark 讀取目錄定義,並產生 Iceberg REST Catalog Spark 屬性。只有叢集形式會採用 dataproc: 前置字元。

支援的映像檔和執行階段版本:

簡化設定和手動設定都會使用 Google 授權 Iceberg (GoogleAuthManager),這需要下列其中一個版本:

  • Managed Service for Apache Spark 叢集:2.2 以上版本映像檔 2.2.65,或 2.3 以上版本映像檔 2.3.11。
  • Managed Service for Apache Spark 無伺服器批次工作負載和互動式工作階段:2.2 執行階段 2.2.60 以上版本、2.3 執行階段 2.3.10 以上版本,或 3.0 執行階段。

如要執行無伺服器批次工作負載和互動式工作階段,所需角色取決於執行階段版本。執行階段 3.0 以上版本預設會使用使用者憑證。詳情請參閱「必要的角色」。

叢集

使用簡化的設定屬性 (建議做法),或在筆記本中手動指定目錄屬性,建立含有 Iceberg 和 Jupyter 選用元件的 Managed Service for Apache Spark 叢集。

使用屬性簡化設定 (建議)

使用目錄屬性建立叢集:

gcloud dataproc clusters create CLUSTER_NAME \
  --project=PROJECT_ID \
  --region=REGION \
  --image-version=IMAGE_VERSION \
  --optional-components=ICEBERG,JUPYTER \
  --enable-component-gateway \
  --properties='dataproc:dataproc.lineage.enabled=true,dataproc:dataproc.lakehouse.catalog.CATALOG_NAME=projects/PROJECT_ID/catalogs/CATALOG_ID,spark:spark.sql.defaultCatalog=CATALOG_NAME'

更改下列內容:

  • CLUSTER_NAME:叢集名稱。
  • PROJECT_ID:您的Google Cloud 專案 ID。
  • REGION:叢集的 Google Cloud區域,例如 us-central1。
  • IMAGE_VERSION:Managed Service for Apache Spark 映像檔版本,例如 2.3-debian12。請參閱「支援的映像檔和執行階段版本」。
  • CATALOG_NAME:本機 Spark 目錄的名稱,例如 iceberg_catalog。可以與 CATALOG_ID 相同。
  • CATALOG_ID:您在「事前準備」中建立的目錄 ID。

dataproc:dataproc.lineage.enabled=true 屬性並非必要,Lakehouse 執行階段目錄 Iceberg REST 目錄仍可正常運作。在資料歷程範例中,這個標籤用於追蹤歷程。

使用 Jupyter 筆記本 (Vertex AI Workbench 筆記本或在叢集上啟動的筆記本) 連線至叢集,並建立 SparkSession,不指定目錄設定:

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("APP_NAME").getOrCreate()

將 APP_NAME 替換為 Spark 應用程式名稱。

手動設定

如果不使用簡化設定屬性,請按照前述步驟建立叢集,但 --properties 旗標中不含 dataproc:dataproc.lakehouse.catalog.,然後連線至 Jupyter 筆記本,並手動設定 SparkSession,如下所示:

import pyspark
from pyspark.context import SparkContext
from pyspark.sql import SparkSession

catalog_name = "CATALOG_NAME"

spark = SparkSession.builder.appName("APP_NAME") \
.config('spark.sql.defaultCatalog', catalog_name) \
.config(f'spark.sql.catalog.{catalog_name}', 'org.apache.iceberg.spark.SparkCatalog') \
.config(f'spark.sql.catalog.{catalog_name}.type', 'rest') \
.config(f'spark.sql.catalog.{catalog_name}.uri', 'https://biglake.googleapis.com/iceberg/v1/restcatalog') \
.config(f'spark.sql.catalog.{catalog_name}.warehouse', 'WAREHOUSE_PATH') \
.config(f'spark.sql.catalog.{catalog_name}.header.x-goog-user-project', 'PROJECT_ID') \
.config(f'spark.sql.catalog.{catalog_name}.rest.auth.type', 'org.apache.iceberg.gcp.auth.GoogleAuthManager') \
.config(f'spark.sql.catalog.{catalog_name}.io-impl', 'org.apache.iceberg.gcp.gcs.GCSFileIO') \
.config('spark.sql.extensions', 'org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions') \
.getOrCreate()

更改下列內容:

  • CATALOG_NAME:本機 Spark 目錄的名稱,例如 iceberg_catalog。
  • APP_NAME:Spark 應用程式的名稱。
  • WAREHOUSE_PATH:倉庫的路徑。如果是多值區目錄 (建議做法),請使用 bl://projects/PROJECT_ID/catalogs/CATALOG_ID。如果是單一 bucket 目錄,請使用 gs://CLOUD_STORAGE_BUCKET_NAME。
  • PROJECT_ID:您的 Google Cloud 專案 ID。
使用憑證臨時配發功能進行設定

如要使用憑證販售功能,您必須使用憑證販售模式的目錄,並將 X-Iceberg-Access-Delegation 標頭新增至 Iceberg REST 目錄要求,方法是在 SparkSession 建構工具中新增下列程式碼行,並將值設為 vended-credentials:

.config(f'spark.sql.catalog.{catalog_name}.header.X-Iceberg-Access-Delegation', 'vended-credentials')

以下範例使用憑證販售功能設定 SparkSession:

from pyspark.sql import SparkSession

catalog_name = "CATALOG_NAME"

spark = SparkSession.builder.appName("APP_NAME") \
.config('spark.sql.defaultCatalog', catalog_name) \
.config(f'spark.sql.catalog.{catalog_name}', 'org.apache.iceberg.spark.SparkCatalog') \
.config(f'spark.sql.catalog.{catalog_name}.type', 'rest') \
.config(f'spark.sql.catalog.{catalog_name}.uri', 'https://biglake.googleapis.com/iceberg/v1/restcatalog') \
.config(f'spark.sql.catalog.{catalog_name}.warehouse', 'WAREHOUSE_PATH') \
.config(f'spark.sql.catalog.{catalog_name}.header.x-goog-user-project', 'PROJECT_ID') \
.config(f'spark.sql.catalog.{catalog_name}.rest.auth.type', 'org.apache.iceberg.gcp.auth.GoogleAuthManager') \
.config(f'spark.sql.catalog.{catalog_name}.io-impl', 'org.apache.iceberg.gcp.gcs.GCSFileIO') \
.config(f'spark.sql.catalog.{catalog_name}.header.X-Iceberg-Access-Delegation', 'vended-credentials') \
.config('spark.sql.extensions', 'org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions') \
.getOrCreate()

如果目錄使用憑證販售模式,簡化設定會新增這個標頭。詳情請參閱 Iceberg 說明文件中的「 Headers in the RESTCatalog 」一節。

無伺服器

使用簡化的設定屬性 (建議),或手動指定目錄屬性,將 PySpark 批次工作負載提交至 Managed Service for Apache Spark 無伺服器。

使用屬性簡化設定 (建議)

提交批次工作負載時,請傳遞 dataproc.lakehouse.catalog.CATALOG_NAME 屬性 (不含 dataproc: 前置字元):

gcloud dataproc batches submit pyspark PYSPARK_FILE \
  --project=PROJECT_ID \
  --region=REGION \
  --version=RUNTIME_VERSION \
  --properties="dataproc.lakehouse.catalog.CATALOG_NAME=projects/PROJECT_ID/catalogs/CATALOG_ID,spark.sql.defaultCatalog=CATALOG_NAME"

更改下列內容:

  • PYSPARK_FILE:PySpark 應用程式檔案的 gs:// Cloud Storage 路徑。
  • PROJECT_ID:您的Google Cloud 專案 ID。
  • REGION:批次工作負載的區域。
  • RUNTIME_VERSION:Managed Service for Apache Spark 無伺服器執行階段版本,例如 3.0。必要角色取決於執行階段版本 (請參閱「支援的映像檔和執行階段版本」)。
  • CATALOG_NAME:本機 Spark 目錄的名稱,例如 iceberg_catalog。可以與 CATALOG_ID 相同。
  • CATALOG_ID:您在「事前準備」中建立的目錄 ID。

在 PySpark 應用程式檔案中,建立 SparkSession,但不指定目錄設定:

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("APP_NAME").getOrCreate()

手動設定

如果未使用簡化設定屬性,請在提交批次工作負載時,於 --properties 標記中指定目錄屬性:

gcloud dataproc batches submit pyspark PYSPARK_FILE \
  --project=PROJECT_ID \
  --region=REGION \
  --version=RUNTIME_VERSION \
  --properties="\
spark.sql.defaultCatalog=CATALOG_NAME,\
spark.sql.catalog.CATALOG_NAME=org.apache.iceberg.spark.SparkCatalog,\
spark.sql.catalog.CATALOG_NAME.type=rest,\
spark.sql.catalog.CATALOG_NAME.uri=https://biglake.googleapis.com/iceberg/v1/restcatalog,\
spark.sql.catalog.CATALOG_NAME.warehouse=WAREHOUSE_PATH,\
spark.sql.catalog.CATALOG_NAME.header.x-goog-user-project=PROJECT_ID,\
spark.sql.catalog.CATALOG_NAME.rest.auth.type=org.apache.iceberg.gcp.auth.GoogleAuthManager,\
spark.sql.catalog.CATALOG_NAME.io-impl=org.apache.iceberg.gcp.gcs.GCSFileIO,\
spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"

將 WAREHOUSE_PATH 替換為倉儲路徑。如有多個目錄值區 (建議做法),請使用 bl://projects/PROJECT_ID/catalogs/CATALOG_ID。 如果是單一 bucket 目錄,請使用 gs://CLOUD_STORAGE_BUCKET_NAME。

使用憑證臨時配發功能設定

如要使用憑證販售功能,您必須使用憑證販售模式的目錄,並在 --properties 旗標中加入下列屬性,將 X-Iceberg-Access-Delegation 標頭新增至 Iceberg REST 目錄要求,值為 vended-credentials:

spark.sql.catalog.CATALOG_NAME.header.X-Iceberg-Access-Delegation=vended-credentials

下列範例會提交具備憑證販售功能的批次工作負載:

gcloud dataproc batches submit pyspark PYSPARK_FILE \
  --project=PROJECT_ID \
  --region=REGION \
  --version=RUNTIME_VERSION \
  --properties="\
spark.sql.defaultCatalog=CATALOG_NAME,\
spark.sql.catalog.CATALOG_NAME=org.apache.iceberg.spark.SparkCatalog,\
spark.sql.catalog.CATALOG_NAME.type=rest,\
spark.sql.catalog.CATALOG_NAME.uri=https://biglake.googleapis.com/iceberg/v1/restcatalog,\
spark.sql.catalog.CATALOG_NAME.warehouse=WAREHOUSE_PATH,\
spark.sql.catalog.CATALOG_NAME.header.x-goog-user-project=PROJECT_ID,\
spark.sql.catalog.CATALOG_NAME.rest.auth.type=org.apache.iceberg.gcp.auth.GoogleAuthManager,\
spark.sql.catalog.CATALOG_NAME.io-impl=org.apache.iceberg.gcp.gcs.GCSFileIO,\
spark.sql.catalog.CATALOG_NAME.header.X-Iceberg-Access-Delegation=vended-credentials,\
spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"

如果目錄使用憑證販售模式,簡化設定會新增這個標頭。詳情請參閱 Iceberg 說明文件中的「 Headers in the RESTCatalog 」一節。

無伺服器

使用 DataprocSparkSession API,透過筆記本建立 Managed Service for Apache Spark 無伺服器互動式工作階段,並使用簡化的設定屬性 (建議做法),或手動指定目錄屬性。

使用屬性簡化設定 (建議)

在安裝 dataproc-spark-connect 套件的筆記本中 (例如 BigQuery Studio 筆記本或 Vertex AI Workbench 筆記本),建立工作階段時請傳遞 dataproc.lakehouse.catalog.CATALOG_NAME 屬性 (不含 dataproc: 前置字元):

from google.cloud.dataproc_spark_connect import DataprocSparkSession
from google.cloud.dataproc_v1 import Session

catalog_name = "CATALOG_NAME"

session_config = Session()
session_config.runtime_config.version = 'RUNTIME_VERSION'

spark = DataprocSparkSession.builder.appName("APP_NAME") \
.dataprocSessionConfig(session_config) \
.config(f'dataproc.lakehouse.catalog.{catalog_name}', 'projects/PROJECT_ID/catalogs/CATALOG_ID') \
.config('spark.sql.defaultCatalog', catalog_name) \
.getOrCreate()

更改下列內容:

  • CATALOG_NAME:本機 Spark 目錄的名稱,例如 iceberg_catalog。可以與 CATALOG_ID 相同。
  • RUNTIME_VERSION:Managed Service for Apache Spark 無伺服器執行階段版本,例如 3.0。必要角色取決於執行階段版本 (請參閱「支援的映像檔和執行階段版本」)。
  • APP_NAME:Spark 應用程式的名稱。
  • PROJECT_ID:您的 Google Cloud 專案 ID。
  • CATALOG_ID:您在「事前準備」中建立的目錄 ID。

您也可以在工作階段範本中設定這些屬性。

手動設定

如果不使用簡化設定屬性,請在建立工作階段時指定目錄屬性:

from google.cloud.dataproc_spark_connect import DataprocSparkSession
from google.cloud.dataproc_v1 import Session

catalog_name = "CATALOG_NAME"

session_config = Session()
session_config.runtime_config.version = 'RUNTIME_VERSION'

spark = DataprocSparkSession.builder.appName("APP_NAME") \
.dataprocSessionConfig(session_config) \
.config('spark.sql.defaultCatalog', catalog_name) \
.config(f'spark.sql.catalog.{catalog_name}', 'org.apache.iceberg.spark.SparkCatalog') \
.config(f'spark.sql.catalog.{catalog_name}.type', 'rest') \
.config(f'spark.sql.catalog.{catalog_name}.uri', 'https://biglake.googleapis.com/iceberg/v1/restcatalog') \
.config(f'spark.sql.catalog.{catalog_name}.warehouse', 'WAREHOUSE_PATH') \
.config(f'spark.sql.catalog.{catalog_name}.header.x-goog-user-project', 'PROJECT_ID') \
.config(f'spark.sql.catalog.{catalog_name}.rest.auth.type', 'org.apache.iceberg.gcp.auth.GoogleAuthManager') \
.config(f'spark.sql.catalog.{catalog_name}.io-impl', 'org.apache.iceberg.gcp.gcs.GCSFileIO') \
.config('spark.sql.extensions', 'org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions') \
.getOrCreate()

按照本分頁中簡化設定範例的說明,替換 RUNTIME_VERSION。

將 WAREHOUSE_PATH 替換為倉儲路徑。如有多個目錄值區 (建議做法),請使用 bl://projects/PROJECT_ID/catalogs/CATALOG_ID。 如果是單一 bucket 目錄,請使用 gs://CLOUD_STORAGE_BUCKET_NAME。

使用憑證臨時配發功能設定

如要使用憑證販售功能,您必須使用憑證販售模式的目錄,並在工作階段建構工具中加入下列程式碼,將 X-Iceberg-Access-Delegation 標頭新增至 Iceberg REST 目錄要求,值為 vended-credentials:

.config(f'spark.sql.catalog.{catalog_name}.header.X-Iceberg-Access-Delegation', 'vended-credentials')

以下範例說明如何建立工作階段,並啟用憑證販售功能:

from google.cloud.dataproc_spark_connect import DataprocSparkSession
from google.cloud.dataproc_v1 import Session

catalog_name = "CATALOG_NAME"

session_config = Session()
session_config.runtime_config.version = 'RUNTIME_VERSION'

spark = DataprocSparkSession.builder.appName("APP_NAME") \
.dataprocSessionConfig(session_config) \
.config('spark.sql.defaultCatalog', catalog_name) \
.config(f'spark.sql.catalog.{catalog_name}', 'org.apache.iceberg.spark.SparkCatalog') \
.config(f'spark.sql.catalog.{catalog_name}.type', 'rest') \
.config(f'spark.sql.catalog.{catalog_name}.uri', 'https://biglake.googleapis.com/iceberg/v1/restcatalog') \
.config(f'spark.sql.catalog.{catalog_name}.warehouse', 'WAREHOUSE_PATH') \
.config(f'spark.sql.catalog.{catalog_name}.header.x-goog-user-project', 'PROJECT_ID') \
.config(f'spark.sql.catalog.{catalog_name}.rest.auth.type', 'org.apache.iceberg.gcp.auth.GoogleAuthManager') \
.config(f'spark.sql.catalog.{catalog_name}.io-impl', 'org.apache.iceberg.gcp.gcs.GCSFileIO') \
.config(f'spark.sql.catalog.{catalog_name}.header.X-Iceberg-Access-Delegation', 'vended-credentials') \
.config('spark.sql.extensions', 'org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions') \
.getOrCreate()

如果目錄使用憑證販售模式,簡化設定會新增這個標頭。詳情請參閱 Iceberg 說明文件的「RESTCatalog 中的標頭」一節。

使用 Spark SQL 管理資料

設定 Spark 工作階段後,即可使用 Spark SQL 執行資料管理作業。

設定目錄:dataproc.lakehouse.catalog. 屬性會向 Spark 註冊目錄,但不會將其設為「預設」目錄。上一節的範例會設定叢集上的 spark.sql.defaultCatalog (spark:spark.sql.defaultCatalog),因此您可以使用不合格的資料表名稱。如果省略該屬性,請在資料表名稱前加上目錄名稱,例如 CATALOG_NAME.NAMESPACE_NAME.base_table。

  1. 建立命名空間。在 Lakehouse 執行階段目錄 Iceberg REST 目錄中,命名空間對應至 BigQuery 資料集。

    spark.sql("CREATE NAMESPACE IF NOT EXISTS NAMESPACE_NAME")
    spark.sql("USE NAMESPACE_NAME")
    

    將 NAMESPACE_NAME 替換為命名空間的名稱,例如 spark_lakehouse。

  2. 以 Iceberg 格式建立基礎資料表並插入資料。

    spark.sql("DROP TABLE IF EXISTS base_table PURGE")
    spark.sql("CREATE TABLE base_table (id LONG) USING iceberg")
    spark.sql("INSERT INTO base_table VALUES 0, 1, 2, 3, 4")
    spark.sql("SELECT * FROM base_table").show()
    

    輸出結果會與下列內容相似:

       +---+
       | id|
       +---+
       |  0|
       |  1|
       |  2|
       |  3|
       |  4|
       +---+
    
  3. 為新資料建立另一個資料表。

    spark.sql("DROP TABLE IF EXISTS newdata PURGE")
    spark.sql("CREATE TABLE newdata(id LONG) USING iceberg")
    spark.sql("INSERT INTO newdata VALUES 3, 4, 5, 6")
    spark.sql("SELECT * FROM newdata").show()
    

    輸出結果會與下列內容相似:

       +---+
       | id|
       +---+
       |  3|
       |  4|
       |  5|
       |  6|
       +---+
    
  4. 將新資料合併至基礎資料表。

    spark.sql("""MERGE INTO base_table USING newdata
               ON base_table.id = newdata.id
               WHEN MATCHED THEN
                 UPDATE SET base_table.id = newdata.id
               WHEN NOT MATCHED THEN INSERT * """)
    spark.sql("SELECT * FROM base_table").show()
    

    輸出結果會與下列內容相似:

       +---+
       | id|
       +---+
       |  0|
       |  1|
       |  2|
       |  3|
       |  4|
       |  5|
       |  6|
       +---+
    
  5. 更新基礎資料表中的記錄。

    spark.sql(
         "UPDATE base_table SET id = (id + 100) WHERE (id % 2 == 0)"
     )
    spark.sql("SELECT * FROM base_table").show()
    

    輸出結果會與下列內容相似:

       +---+
       | id|
       +---+
       |  3|
       |104|
       |  5|
       |106|
       |100|
       |102|
       |  1|
       +---+
    
  6. 從基礎資料表刪除記錄。

    spark.sql("DELETE FROM base_table WHERE (id % 2 == 0)")
    spark.sql("SELECT * FROM base_table").show()
    

    輸出結果會與下列內容相似:

       +---+
       | id|
       +---+
       |  3|
       |  5|
       |  1|
       +---+
    

查詢歷來快照

查詢快照 ID,擷取資料表的先前版本。這項作業也稱為「時空旅行」。

  1. 擷取 MERGE、UPDATE 和 DELETE 作業之前的資料表版本快照 ID。

    snapshot_ids = spark.sql(
         "SELECT snapshot_id FROM `NAMESPACE_NAME`.`base_table`.snapshots"
    ).collect()
    oldest_snapshot_id = snapshot_ids[1]["snapshot_id"]
    

    將 NAMESPACE_NAME 替換為您建立的命名空間。

  2. 使用擷取的快照 ID 查詢資料表。

    df = (
         spark.read.format("iceberg")
         .option("versionAsOf", oldest_snapshot_id)
         .load("base_table")
     )
    df.show()
    

    輸出內容會顯示 MERGE 作業之後,但在 UPDATE 或 DELETE 作業之前的資料表狀態。

       +---+
       | id|
       +---+
       |  0|
       |  1|
       |  2|
       |  3|
       |  4|
       |  5|
       |  6|
       +---+
    

探索資料歷程

使用 Managed Service for Apache Spark 2.2 以上版本的映像檔,即可透過資料歷程,追蹤 Lakehouse 執行階段目錄 Iceberg REST 目錄資料表之間的資料移動。

資料歷程範例

  1. 建立來源和目標 Iceberg 資料表,然後複製資料。

    spark.sql("DROP TABLE IF EXISTS source_table PURGE")
    spark.sql("DROP TABLE IF EXISTS target_table PURGE")
    spark.sql("CREATE TABLE source_table (id LONG) USING iceberg")
    spark.sql("""CREATE TABLE target_table
      USING ICEBERG
      AS SELECT max(id) as top_id FROM source_table
      """)
    
  2. 在 Google Cloud 控制台,前往 Knowledge Catalog 的「Search」(搜尋) 頁面。

    前往「Search」(搜尋) 頁面

  3. 搜尋其中一個資料表,然後按一下「Lineage」分頁標籤:

     Google Cloud 控制台 Knowledge Catalog 頁面中的資料歷程範例。
    Google Cloud 控制台 Knowledge Catalog 頁面中的資料歷程圖範例。

    資料歷程可辨識 Lakehouse 執行階段目錄 Iceberg REST 目錄資料表的邏輯 (Lakehouse 執行階段目錄資料表) 和實體 (Cloud Storage) 表示法。

資料歷程已知問題

在某些 Managed Service for Apache Spark 叢集中,由於 OpenLineage 程式庫問題,可能無法產生完整的資料歷程。這是已知限制。如果這項異動會影響工作負載,請與 Google Cloud 支援團隊聯絡。

後續步驟