使用 Delta 表的液態叢集
Delta Lake 液態叢集會取代資料表分區,進而簡化資料配置決策,並優化查詢效能。 液態叢集可讓您彈性地重新定義叢集索引鍵,而不需要重寫現有的資料,讓資料配置隨著時間的分析需求演進。 Liquid 叢集同時適用於串流資料表和實體化視圖。
重要
Databricks 建議針對已啟用液體叢集的所有數據表使用 Databricks Runtime 15.2 和更新版本。 Databricks Runtime 13.3 LTS 和更新版本提供具有限制的公開預覽支援。
注意
啟用了液態分群的資料表支援 Databricks Runtime 13.3 LTS 及更高版本中的列層級並行操作。 Databricks Runtime 14.2 和更新版本通常會針對已啟用刪除向量的所有數據表,提供數據列層級並行存取。 請參閱 Azure Databricks 上的隔離等級和寫入衝突。
液體群集有什麼用途?
Databricks 建議對所有新的 Delta 表使用液態叢集,這包括串流表(ST)和具現化檢視(MV)。 以下是受益於叢集的案例範例:
- 資料表格通常會依高基數欄位進行篩選。
- 資料分布顯著偏斜的資料表。
- 快速成長且需要維護和微調的資料表。
- 具有並行寫入需求的資料表。
- 具有隨時間變更之存取模式的資料表。
- 資料表中,典型的分割索引鍵可能會導致該資料表擁有過多或過少的資料分割區。
啟用液體群集
您可以在現有資料表或資料表建立期間啟用液體叢集。 叢集與數據分割或 ZORDER
不相容,而且您必須使用 Azure Databricks 來管理數據表中數據的所有配置和優化作業。 啟用液體叢集之後,請像往常一樣執行 OPTIMIZE
作業,以累加方式叢集數據。 請參閱 如何觸發叢集。
要啟用 Liquid Clustering,請在建立數據表的語句中新增 CLUSTER BY
,如下列範例所示:
注意
在 Databricks Runtime 14.2 和更新版本中,您可以使用 Python 或 Scala 中的 DataFrame API 和 DeltaTable API 來啟用液體叢集。
SQL
-- Create an empty 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;
Python
# Create an empty 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 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 和更新版本中,您可以使用結構化串流寫入來建立已啟用液體叢集的數據表,如下列範例所示:
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 Lake 用戶端讀取。 請參閱 Azure Databricks 如何管理 Delta Lake 功能相容性?。
您可以使用下列語法,在現有的未分割 Delta 資料表上啟用液體叢集:
ALTER TABLE <table_name>
CLUSTER BY (<clustering_columns>)
重要
默認行為不會將叢集套用至先前寫入的數據。 若要強制對所有記錄重新分群,您必須使用 OPTIMIZE FULL
。 請參見對所有記錄進行強制重新群集。
若要移除叢集索引鍵,請使用下列語法:
ALTER TABLE table_name CLUSTER BY NONE;
自動液體群集
重要
自動液體叢集 公開預覽版。
在 Databricks Runtime 15.4 LTS 和更新版本中,您可以啟用 Unity 目錄受控數據表的自動液體叢集。 啟用自動液體叢集後,Azure Databricks 會以智慧方式選擇叢集密鑰來優化查詢效能。 您可以使用 CLUSTER BY AUTO
子句來啟用自動液體叢集。
啟用時,自動選取金鑰和叢集作業會以異步方式執行作為維護作業,並要求為數據表啟用預測優化。 請參閱 Unity Catalog 受控資料表的預測性最佳化。
為了識別叢集索引鍵,Azure Databricks 會分析數據表的歷史查詢工作負載,並識別最佳的候選數據行。 當預測的數據略過改進所帶來的成本節省超過叢集數據的成本時,叢集鍵會被改變。
如果您在一段時間內查詢資料的方式發生變化,或查詢性能顯示資料分佈的變更,自動化的 Liquid Clustering 會選擇新的鍵值來優化性能。
注意
您可以在支援液體叢集的所有 Databricks Runtime 版本中讀取或寫入具有自動叢集功能的表格,但智慧型密鑰選取依賴於在 Databricks Runtime 15.4 LTS 中引入的元數據。 使用 Databricks Runtime 15.4 LTS 或更新版本來確保自動選取的密鑰有利於您所有的工作負載,並在選取新密鑰時考慮這些工作負載。
啟用或停用自動叢集
若要建立已啟用自動液體群集的新數據表,請使用下列語法:
CREATE OR REPLACE TABLE table_name CLUSTER BY AUTO;
您也可以在現有的數據表上啟用自動液體叢集,包括先前已手動指定索引鍵的數據表,如下列範例所示:
ALTER TABLE table_name CLUSTER BY AUTO;
您也可以變更已啟用自動液體群集的數據表,以使用手動指定的索引鍵。
注意
當您啟用自動液體群集時,clusterByAuto
屬性會設定為 true
。
clusteringColumns
屬性顯示由自動索引鍵選擇功能選取的當前叢集欄。 執行 DESCRIBE EXTENDED table_name
以查看資料表屬性的完整清單。
覆寫預設功能啟用(可選)
您可以覆寫在啟用液態聚類時啟用 Delta 表格功能的預設行為。 這可防止與這些數據表功能相關聯的讀取器和寫入器通訊協議升級。 您必須有現有的資料表,才能完成下列步驟:
使用
ALTER TABLE
來設定停用一或多個功能的數據表屬性。 例如,若要停用刪除向量,請執行下列動作:ALTER TABLE table_name SET TBLPROPERTIES ('delta.enableDeletionVectors' = false);
執行下列命令,在資料表上啟用液體叢集:
ALTER TABLE <table_name> CLUSTER BY (<clustering_columns>)
下表提供您可以覆寫的 Delta 特徵的相關信息,以及啟用會如何影響與 Databricks Runtime 版本的相容性。
增量特性 | 執行時間相容性 | 覆蓋啟用狀態的屬性 | 停用對液體群集的影響 |
---|---|---|---|
刪除向量 | 讀取和寫入需要 Databricks Runtime 12.2 LTS 和更新版本。 | 'delta.enableDeletionVectors' = false |
數據列層級並行存取已停用,使得交易和叢集作業更有可能發生衝突。 請參閱列級並發性寫入衝突。DELETE 、 MERGE 和 UPDATE 命令的執行速度可能會變慢。 |
資料列追蹤 | 寫入需要 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 或更新版本)
- 字串
- 整數
- Long
- 短
- 浮動
- 加倍
- Decimal
- Byte
如果您要轉換現有的數據表,請考慮下列建議:
目前的數據優化技術 | 叢集金鑰的建議 |
---|---|
Hive 樣式分區 | 使用分割區數據行作為叢集索引鍵。 |
Z 順序索引編製 | 使用 ZORDER BY 列用作叢集索引鍵。 |
Hive 風格的資料分割和 Z 順序 | 同時使用分區列和 ZORDER BY 列作為叢集鍵。 |
自動產生的字段用于降低基數(例如,從時間戳中提取的日期) | 使用原始數據行作為叢集索引鍵,而且不會建立產生的數據行。 |
將數據寫入叢集數據表
您必須使用支援液體叢集使用之所有 Delta 寫入通訊協定資料表功能的 Delta 寫入器用戶端。 在 Azure Databricks 上,您必須使用 Databricks Runtime 13.3 LTS 和更新版本。
寫入時叢集的操作包括以下各項:
-
INSERT INTO
運作 -
CTAS
和RTAS
語句 -
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 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 FULL
,以確保數據配置反映目前的叢集索引鍵。
從叢集數據表讀取數據
您可以使用支援讀取刪除向量的任何 Delta Lake 用戶端,讀取叢集數據表中的數據。 如需最佳查詢結果,請在查詢篩選中包含叢集索引鍵,如下列範例所示:
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
作業使用叢集密鑰。
查看數據表的叢集方式
您可以使用 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 資料表功能。
限制
存在下列限制:
- 在 Databricks Runtime 15.1 和以下版本中,寫入上的叢集不支援包含篩選、聯結或匯總的來源查詢。
- 結構化串流工作負載不支援寫入時叢集處理。
- 在 Databricks Runtime 15.4 LTS 和下方,您無法使用結構化串流寫入來建立已啟用液體叢集的數據表。 您可以使用結構化串流將資料寫入已啟用液體叢集的現有資料表。