共用方式為


針對數據表使用液體叢集

Liquid 群集取代了表分區和ZORDER,以便簡化資料佈局決策並優化查詢效能。 它可讓您彈性地重新定義叢集索引鍵,而不需重寫現有的數據,讓數據配置隨著時間而隨著分析需求而演進。 Liquid 叢集同時適用於串流資料表和實體化視圖。

重要

液態叢集功能已在 Delta Lake 正式推出,並在 Apache Iceberg 提供公開預覽。

針對已啟用液體叢集的所有 Delta Lake 數據表,Databricks 建議使用 Databricks Runtime 15.2 和更新版本。 Databricks Runtime 13.3 LTS 和更新版本提供具有限制的公開預覽支援。 Databricks Runtime 13.3 LTS 和更高版本支援列級並行性,而從 Databricks Runtime 14.2 和更高版本開始,一般可用於所有啟用刪除向量的數據表。 請參閱 Azure Databricks 上的隔離等級和寫入衝突

針對已啟用液體叢集的所有 Apache Iceberg 數據表,需要 Databricks Runtime 16.4 LTS 和更新版本。

液體群集有什麼用途?

Databricks 建議針對所有新的數據表進行液體群集,其中包括串流數據表 (ST) 和具體化檢視 (MV)。 以下是受益於叢集的案例範例:

  • 資料表格通常會依高基數欄位進行篩選。
  • 資料分布顯著偏斜的資料表。
  • 快速增長且需要維護和調整的資料表。
  • 具有並行寫入需求的資料表。
  • 具有隨時間變更之存取模式的資料表。
  • 資料表中,典型的分割索引鍵可能會導致該資料表擁有過多或過少的資料分割區。

啟用液體群集

您可以在現有資料表或資料表建立期間啟用液體叢集。 叢集與數據分割或 ZORDER不相容,而且您必須使用 Azure Databricks 來管理數據表中數據的所有配置和優化作業。 啟用液體叢集之後,請像往常一樣執行 OPTIMIZE 作業,以累加方式叢集數據。 請參閱 如何觸發叢集

要啟用 Liquid Clustering,請在建立數據表的語句中新增 CLUSTER BY,如下列範例所示:

注意

在 Databricks Runtime 14.2 和更新版本中,您可以使用 Python 或 Scala 中的 DataFrame API 和 DeltaTable API 來啟用 Delta Lake 數據表的液體叢集。

SQL

-- Create an empty Delta table
CREATE TABLE table1(col0 INT, col1 string) CLUSTER BY (col0);

-- Using a CTAS statement
CREATE EXTERNAL TABLE table2 CLUSTER BY (col0)  -- specify clustering after table name, not in subquery
LOCATION 'table_location'
AS SELECT * FROM table1;

-- Using a LIKE statement to copy configurations
CREATE TABLE table3 LIKE table1;

針對 Apache Iceberg,您必須在 Managed Iceberg 數據表上啟用液體群集時,明確停用刪除向量和數據列標識碼。

Python(程式語言)

# Create an empty Delta table
(DeltaTable.create()
  .tableName("table1")
  .addColumn("col0", dataType = "INT")
  .addColumn("col1", dataType = "STRING")
  .clusterBy("col0")
  .execute())

# Using a CTAS statement
df = spark.read.table("table1")
df.write.clusterBy("col0").saveAsTable("table2")

# CTAS using DataFrameWriterV2
df = spark.read.table("table1")
df.writeTo("table1").using("delta").clusterBy("col0").create()

程式語言 Scala

// Create an empty Delta table
DeltaTable.create()
  .tableName("table1")
  .addColumn("col0", dataType = "INT")
  .addColumn("col1", dataType = "STRING")
  .clusterBy("col0")
  .execute()

// Using a CTAS statement
val df = spark.read.table("table1")
df.write.clusterBy("col0").saveAsTable("table2")

// CTAS using DataFrameWriterV2
val df = spark.read.table("table1")
df.writeTo("table1").using("delta").clusterBy("col0").create()

在 Databricks Runtime 16.0 和更新版本中,您可以使用結構化串流寫入來建立已啟用液體叢集的數據表,如下列範例所示:

:::

SQL

CREATE TABLE table1 (
  col0 STRING,
  col1 DATE,
  col2 BIGINT
)
CLUSTER BY (col0, col1)
TBLPROPERTIES (
  'clusterByAuto' = 'true'
);

Python(程式語言)

(spark.readStream.table("source_table")
  .writeStream
  .clusterBy("column_name")
  .option("checkpointLocation", checkpointPath)
  .toTable("target_table")
)

程式語言 Scala

spark.readStream.table("source_table")
  .writeStream
  .clusterBy("column_name")
  .option("checkpointLocation", checkpointPath)
  .toTable("target_table")

警告

使用已啟用液體叢集建立的 Delta 數據表,在建立和使用 Delta 寫入器第 7 版和讀取器第 3 版時啟用許多 Delta 數據表功能。 您可以覆寫某些功能的啟用狀態。 請參閱 覆蓋預設功能啟用 (選擇性)

數據表通訊協定版本無法降級,且已啟用叢集的數據表無法由不支援所有已啟用 Delta 讀取器通訊協定數據表功能的 Delta Lake 用戶端讀取。 請參閱 Delta Lake 功能相容性和通訊協定

使用下列語法,在現有未分割的 Delta 資料表上啟用液體叢集:

-- Alter an existing table
ALTER TABLE <table_name>
CLUSTER BY (<clustering_columns>)

針對 Apache Iceberg,您必須在現有的 Managed Iceberg 數據表上啟用液體群集時,明確停用刪除向量和數據列標識符。

重要

默認行為不會將叢集套用至先前寫入的數據。 若要強制對所有記錄重新分群,您必須使用 OPTIMIZE FULL。 請參見對所有記錄進行強制重新群集

若要移除叢集索引鍵,請使用下列語法:

ALTER TABLE table_name CLUSTER BY NONE;

自動液體群集

在 Databricks Runtime 15.4 LTS 和更新版本中,您可以啟用 Unity Catalog 管理的 Delta 表的自動液體叢集化。 啟用自動液體叢集後,Azure Databricks 會以智慧方式選擇叢集密鑰來優化查詢效能。 您可以使用 CLUSTER BY AUTO 子句來啟用自動液體叢集。

啟用時,自動選取金鑰和叢集作業會以異步方式執行作為維護作業,並要求為數據表啟用預測優化。 請參閱 Unity Catalog 受控資料表的預測性最佳化

為了識別叢集索引鍵,Azure Databricks 會分析數據表的歷程記錄查詢工作負載,並識別最佳的候選數據行。 當預測的成本節省超過數據叢集成本時,叢集索引鍵就會變更。

如果您在一段時間內查詢資料的方式發生變化,或查詢性能顯示資料分佈的變更,自動化的 Liquid Clustering 會選擇新的鍵值來優化性能。

如果自動液體群集未選取金鑰,原因可能是:

  • 表格太小,無法利用液體群集的優勢。
  • 數據表已經有良好的叢集配置。 例如,具有良好的索引曾經套用過,或插入順序在指定的查詢模式中表現良好,例如以時間順序插入的數據,並基於時間戳查詢。
  • 數據表沒有頻繁的查詢。
  • 您不是使用 Databricks Runtime 15.4 LTS 或更新版本。

不論數據和查詢特性為何,您都可以為所有 Unity 目錄受控數據表套用自動液體叢集。 這些功能會根據您的數據使用模式提供智慧型數據配置優化,並且啟發式方法會決定選擇叢集索引鍵是否符合成本效益。

注意

您可以從支援液體叢集的所有 Databricks Runtime 版本,讀取或寫入已啟用自動叢集的數據表。 不過,智慧型密鑰選取依賴 Databricks Runtime 15.4 LTS 中引進的元數據。 使用 Databricks Runtime 15.4 LTS 或更新版本來確保自動選取的密鑰有利於您所有的工作負載,並在選取新密鑰時考慮這些工作負載。

啟用或停用自動液體群集

若要在新的或現有的數據表上啟用或停用自動液體群集,請使用下列語法:

SQL

-- Create an empty table.
CREATE OR REPLACE TABLE table1(column01 int, column02 string) CLUSTER BY AUTO;

-- Enable automatic liquid clustering on an existing table,
-- including tables that previously had manually specified keys.
ALTER TABLE table1 CLUSTER BY AUTO;

-- Disable automatic liquid clustering on an existing table.
ALTER TABLE table1 CLUSTER BY NONE;

-- Disable automatic liquid clustering by setting the clustering keys
-- to chosen clustering columns or new columns.
ALTER TABLE table1 CLUSTER BY (column01, column02);

注意

如果您執行 CREATE OR REPLACE table_name 時未指定 CLUSTER BY AUTO ,且該數據表已經存在並啟用了自動液體群集,那麼在取代數據表時,AUTO 的設定以及該數據表的群集欄位(如果已套用)會被保留。 預測優化也會維護此數據表的歷史查詢工作負載,以識別最佳的叢集索引鍵。

Python(程式語言)

df = spark.read.table("table1")
df.write
  .format("delta")
  .option(“clusterByAuto”, “true”)
  .saveAsTable(...)

# To set clustering columns and auto, which serves as a way to give a hint
# for the initial selection.
df.write
  .format("delta")
  .clusterBy("clusteringColumn1", "clusteringColumn2")
  .option(“clusterByAuto”, “true”)
  .saveAsTable(...)

# Using DataFrameWriterV2
df.writeTo(...).using("delta")
  .option(“clusterByAuto”, “true”)
  .create()

# To set clustering columns and auto, which serves as a way to give a hint
# for the initial selection.
df.writeTo(...).using("delta")
  .clusterBy("clusteringColumn1", "clusteringColumn2")
  .option(“clusterByAuto”, “true”)
  .create()

# Similar syntax can also be used to set clusterByAuto for streaming tables.
spark.readStream.table("source_table")
  .writeStream
  .option("clusterByAuto", "true")
  .option("checkpointLocation", checkpointPath)
  .toTable("target_table")

# Or to specify a hint for the clustering columns by specifying both auto and columns together
spark.readStream.table("source_table")
  .writeStream
 .clusterBy("column1", "column2")
  .option("clusterByAuto", "true")
  .option("checkpointLocation", checkpointPath)
  .toTable("target_table")

注意

Python API 適用於 Databricks Runtime 16.4 和更新版本。

.clusterBy.option('clusterByAuto', 'true) 一起使用時:

  • 如果這是第一次設定自動液體群集,則一律會採用手動輸入,並將叢集數據行設定在 .clusterBy 中。
  • 如果這已經是具有自動液體群集的數據表,則可以接受使用 .clusterBy 的提示一次。 例如,只有當資料表尚未由您或自動液體聚集功能設定聚集欄時,才會設定.clusterBy指定的欄。

您只能在建立或取代數據表時使用 Python。 使用 SQL 來變更 clusterByAuto 現有資料表的狀態。

檢查是否已啟用自動叢集

若要檢查資料表是否已啟用自動液體群集,請使用 DESCRIBE TABLESHOW TBLPROPERTIES

如果已啟用自動液體群集,屬性 clusterByAuto 會設定為 true。 屬性 clusteringColumns 會顯示自動或手動選取的目前叢集數據行。

限制

Apache Iceberg 不支援自動液體分組。

覆寫預設功能啟用(可選)

您可以覆寫在啟用液態聚類時啟用 Delta 表格功能的預設行為。 這可防止與這些數據表功能相關聯的讀取器和寫入器通訊協議升級。 您必須有現有的資料表,才能完成下列步驟:

  1. 使用 ALTER TABLE 來設定停用一或多個功能的數據表屬性。 例如,若要停用刪除向量,請執行下列動作:

    ALTER TABLE table_name SET TBLPROPERTIES ('delta.enableDeletionVectors' = false);
    
  2. 執行下列命令,在資料表上啟用液體叢集:

    ALTER TABLE <table_name>
    CLUSTER BY (<clustering_columns>)
    

下表提供您可以覆寫的 Delta 特徵的相關信息,以及啟用會如何影響與 Databricks Runtime 版本的相容性。

增量特性 執行時間相容性 覆蓋啟用狀態的屬性 停用對液體群集的影響
刪除向量 讀取和寫入需要 Databricks Runtime 12.2 LTS 和更新版本。 'delta.enableDeletionVectors' = false 數據列層級並行存取已停用,使得交易和叢集作業更有可能發生衝突。 請參閱資料列層級並行的寫入衝突
DELETEMERGEUPDATE 命令的執行速度可能會變慢。
列追蹤 寫入操作需要 Databricks Runtime 13.3 LTS 或更高版本。 可以從任何 Databricks Runtime 版本進行讀取。 'delta.enableRowTracking' = false 數據列層級並行存取已停用,使得交易和叢集作業更有可能發生衝突。 請參閱資料列層級並行的寫入衝突
檢查點 V2 讀取和寫入需要 Databricks Runtime 13.3 LTS 和更新版本。 'delta.checkpointPolicy' = 'classic' 不會影響液體群集行為。

選擇叢集金鑰

Databricks 建議針對支持的數據表自動進行液體叢集。 請參閱 自動液體群集

Databricks 建議根據查詢篩選中最常使用的數據行來選擇叢集索引鍵。 叢集索引鍵可以依任何順序定義。 如果兩個數據行高度相互關聯,您只需要將其中一個數據行當做叢集索引鍵來包含。

您可以指定最多四個叢集金鑰。 對於較小的數據表(低於 10 TB),使用更多叢集索引鍵(例如,4 個)在篩選單一數據行時可能會降低效能,而使用較少的叢集索引鍵(例如,2 個)。 不過,隨著數據表大小增加,針對單一數據行查詢使用更多叢集索引鍵的效能差異會變得微不足道。

您只能指定已收集統計數據的欄位作為群集鍵。 依預設,Delta 表中的前 32 欄已收集統計資料。 請參閱指定 Delta 統計資料欄

叢集支援叢集索引鍵的下列資料類型:

  • 日期
  • 時間戳記
  • TimestampNTZ (需要 Databricks Runtime 14.3 LTS 或更新版本)
  • 字串
  • 整數
  • 浮動
  • 兩倍
  • 十進制
  • 位元

如果您要轉換現有的數據表,請考慮下列建議:

目前的數據優化技術 叢集金鑰的建議
Hive 樣式分區 使用分割區數據行作為叢集索引鍵。
Z 順序索引編製 使用 ZORDER BY 列用作叢集索引鍵。
Hive 風格的資料分割和 Z 順序 同時使用分區列和 ZORDER BY 列作為叢集鍵。
自動產生的字段用于降低基數(例如,從時間戳中提取的日期) 使用原始數據行作為叢集索引鍵,而且不會建立產生的數據行。

將數據寫入叢集數據表

若要寫入叢集 Delta 表,您必須使用支持液體叢集使用之所有 Delta 寫入通訊協議表功能的 Delta 寫入器用戶端。 若要寫入叢集的 Iceberg 資料表,您可以使用 Unity 目錄的 Iceberg REST 目錄 API。 在 Azure Databricks 上,您必須使用 Databricks Runtime 13.3 LTS 和更新版本。

寫入時叢集的操作包括以下各項:

  • INSERT INTO 運作
  • CTASRTAS 語句
  • COPY INTO 來自於 Parquet 格式
  • spark.write.mode("append")

結構化串流寫入永遠不會在寫入時觸發叢集。 額外限制適用。 請參閱限制

只有當交易中的數據達到大小閾值時,才會在寫入操作中啟動叢集。 這些臨界值會因叢集列數目而有所不同,Unity Catalog 管理的表格比其他 Delta 表的臨界值更低。

叢集資料欄的數目 Unity Catalog 管理表格的臨界大小 其他 Delta 數據表的臨界值大小
1 64 MB 256 MB
2 256 MB 1 GB
3 512 MB 2 GB
4 1 GB 4 GB

因為並非所有作業都套用液體叢集,因此 Databricks 建議經常執行 OPTIMIZE ,以確保所有數據都能有效率地叢集化。

如何觸發叢集

預測優化會自動對已啟用的資料表執行命令 OPTIMIZE。 請參閱 Unity Catalog 受控資料表的預測性最佳化。 使用預測性優化時,Databricks 建議停用任何排程 OPTIMIZE 的工作。

若要觸發叢集,您必須使用 Databricks Runtime 13.3 LTS 或更新版本。 在資料表中使用 OPTIMIZE 命令:

OPTIMIZE table_name;

液體叢集是累加式的,這表示數據只會視需要重寫,以容納需要叢集的數據。 具有不符合要叢集數據之叢集索引鍵的數據檔不會重寫。

如果您未使用預測性優化,Databricks 建議將一般 OPTIMIZE 作業排程到叢集數據。 對於進行很多更新或插入的數據表,Databricks 建議每隔一兩小時排程一次 OPTIMIZE 作業。 因為液體叢集是累加式的,因此叢集數據表的大部分 OPTIMIZE 作業都會快速執行。

強制將所有記錄重新群集

在 Databricks Runtime 16.0 及更高版本中,您可以使用以下語法來強制重新分群資料表中所有記錄:

OPTIMIZE table_name FULL;

重要

執行 OPTIMIZE FULL 視需要將所有現有的數據重新叢集。 對於先前未在指定索引鍵上叢集的大型數據表,此作業可能需要數小時的時間。

第一次啟用叢集或變更叢集金鑰時,請執行 OPTIMIZE FULL。 如果您先前已執行 OPTIMIZE FULL 且叢集金鑰沒有變更,OPTIMIZE FULL 執行與 OPTIMIZE相同。 在此案例中, OPTIMIZE 會使用累加方法,並只重寫先前尚未壓縮的檔案。 請一律使用 OPTIMIZE FULL,以確保數據配置反映目前的叢集索引鍵。

從叢集數據表讀取數據

您可以使用支援讀取刪除向量的任何 Delta Lake 用戶端,讀取叢集 Delta 資料表中的數據。 使用 Iceberg REST 目錄 API,您可以在叢集 Iceberg 數據表中讀取數據。

SELECT * FROM table_name WHERE cluster_key_column_name = "some_value";

變更叢集金鑰

您可以執行 ALTER TABLE 命令,隨時變更資料表的叢集索引鍵,如下列範例所示:

ALTER TABLE table_name CLUSTER BY (new_column1, new_column2);

當您變更叢集金鑰時,後續 OPTIMIZE 和寫入作業會使用新的叢集方法,但不會重寫現有的數據。

您也可以將金鑰設定為 NONE關閉叢集,如下列範例所示:

ALTER TABLE table_name CLUSTER BY NONE;

將叢集金鑰設定為 NONE 不會重寫已叢集的數據,但可防止未來的 OPTIMIZE 作業使用叢集密鑰。

從外部引擎運用液體群集

您可以在受控管理的 Iceberg 資料表上,透過外部 Iceberg 引擎啟用 Liquid Clustering。 若要啟用液態群集,請在建立數據表時指定分割欄。 Unity 目錄會將分割區解譯為叢集索引鍵。 例如,在 OSS Spark 中執行下列命令:

CREATE OR REPLACE TABLE main.schema.icebergTable
PARTITIONED BY c1;

您可以停用液體群集:

ALTER TABLE main.schema.icebergTable DROP PARTITION FIELD c2;

您可以使用 Iceberg 資料分割演進來變更叢集索引鍵:

ALTER TABLE main.schema.icebergTable ADD PARTITION FIELD c2;

如果您使用桶轉換指定分割區,Unity 目錄將會移除運算式,並使用該欄位作為叢集索引鍵:

CREATE OR REPLACE TABLE main.schema.icebergTable
PARTITIONED BY (bucket(c1, 10));

查看數據表的叢集方式

您可以使用 DESCRIBE 命令來檢視資料表的叢集索引鍵,如下列範例所示:

DESCRIBE TABLE table_name;

DESCRIBE DETAIL table_name;

與液體叢集的數據表相容性

在 Databricks Runtime 14.1 和更高版本中,使用液體群集的數據表會預設使用 v2 檢查點。 您可以在 Databricks Runtime 13.3 LTS 和更新版本中使用 v2 檢查點讀取和寫入數據表。

您可以在 Databricks Runtime 12.2 LTS 和更新版本停用 v2 檢查點和降級數據表通訊協定,以讀取具有液體叢集的數據表。 請參閱 刪除 Delta Lake 資料表功能和降級資料表協議

限制

存在下列限制:

  • 在 Databricks Runtime 15.1 和以下版本中,寫入上的叢集不支援包含篩選、聯結或匯總的來源查詢。
  • 結構化串流工作負載不支援寫入時叢集處理。
  • 在 Databricks Runtime 15.4 LTS 和下方,您無法使用結構化串流寫入來建立已啟用液體叢集的數據表。 您可以使用結構化串流將資料寫入已啟用液體叢集的現有資料表。
  • Managed Iceberg 數據表不支持數據列層級並行,因為 Iceberg 數據表不支援刪除向量和數據列追蹤。