将 liquid 聚类分析用于 Delta 表

Delta Lake liquid 聚类分析取代了表分区和 ZORDER,以简化数据布局决策并优化查询性能。 Liquid 聚类分析提供了在不重写现有数据的情况下重新定义聚类分析键的灵活性,从而使数据布局能够随着分析需求和时间推移而演变。

重要

Databricks 建议对所有启用了 liquid 聚类分析的表使用 Databricks Runtime 15.2 及更高版本。 Databricks Runtime 13.3 LTS 及更高版本中提供了具有限制的公共预览版支持。

注意

在 Databricks Runtime 13.3 LTS 及更高版本中,启用了 Liquid 聚类分析的表支持行级并发。 行级并发已在 Databricks Runtime 14.2 及更高版本上正式发布,适用于启用了删除矢量的所有表。 请参阅 Azure Databricks 上的隔离级别和写入冲突

Liquid 聚类分析的用途是什么?

Databricks 建议对所有新 Delta 表使用 liquid 聚类分析。 下面是受益于聚类分析的情况的示例:

  • 通常按高基数列筛选的表。
  • 数据分布中存在明显偏差的表。
  • 增长迅速且需要维护和优化工作量的表。
  • 具有并发写入要求的表。
  • 访问模式随时间变化的表。
  • 典型分区键可能使表具有过多或过少的分区的表。

启用 liquid 聚类分析

可在现有表上或在表创建期间启用 liquid 聚类。 聚类与分区或 ZORDER 不兼容,并且要求使用 Azure Databricks 管理表中数据的所有布局和优化操作。 启用 liquid 聚类后,像往常一样运行 OPTIMIZE 作业,以增量方式群集数据。 请参阅如何触发聚类分析

若要启用 liquid 聚类分析,请将短语 CLUSTER BY 添加到表创建语句中,如以下示例所示:

注意

在 Databricks Runtime 14.2 及更高版本中,可以在 Python 或 Scala 中使用 DataFrame API 和 DeltaTable API 来启用 liquid 聚类分析。

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()

警告

在启用了 liquid 聚类分析的情况下创建的表在创建时启用了许多 Delta 表功能,并使用 Delta 写入器版本 7 和读取器版本 3。 可以替代其中一些功能的启用。 请参阅替代默认功能启用(可选)

表协议版本不能降级,并且如果 Delta Lake 客户端不支持所有已启用的 Delta 读取器协议表功能,则此客户端无法读取启用聚类分析的表。 请参阅 Azure Databricks 如何管理 Delta Lake 功能兼容性?

可以使用以下语法在现有未分区的 Delta 表上启用 liquid 聚类分析:

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

替代默认功能启用(可选)

可以替代在 liquid 群集启用期间启用 Delta 表功能的默认行为。 这可以防止与这些表功能关联的读取器和编写器协议升级。 必须具有现有表才能完成以下步骤:

  1. 使用 ALTER TABLE 设置会禁用一个或多个功能的表属性。 例如,若要禁用删除矢量,请运行以下命令:

    ALTER TABLE table_name SET TBLPROPERTIES ('delta.enableDeletionVectors' = false);
    
  2. 通过运行以下命令,在表上启用 liquid 群集:

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

在下表中了解你可替代的 Delta 功能,并了解启用如何影响与 Databricks Runtime 版本的兼容性。

Delta 功能 运行时兼容性 用于替代启用的属性 禁用对 liquid 群集的影响
删除向量 读取和写入操作需要 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' 对 liquid 群集行为无影响。

选择群集键

Databricks 建议根据常用的查询筛选器选择群集键。 可按任意顺序定义群集键。 如果两个列相关,只需要将其中一个列添加为群集键。

最多可以指定 4 列作为聚类分析键。 只能指定包含为聚类分析键收集的统计信息的列。 默认情况下,Delta 表中的前 32 列收集统计信息。 请参阅指定增量统计信息列

聚类分析支持以下用于聚类分析键的数据类型:

  • 日期
  • 时间戳
  • TimestampNTZ(需要 Databricks Runtime 14.3 LTS 或更高版本)
  • String
  • Integer
  • Long
  • Short
  • 浮点
  • Double
  • Decimal
  • Byte

若要转换现有表,请考虑以下建议:

当前数据优化技术 有关群集键的建议
Hive 样式分区 使用分区列作为群集键。
Z 顺序索引 使用 ZORDER BY 列作为群集键。
Hive 样式分区和 Z 顺序 将分区列和 ZORDER BY 列用作群集键。
生成的用于减少基数的列(例如,时间戳的日期) 使用原始列作为群集键,不要创建生成的列。

将数据写入聚类分析表

必须使用支持 liquid 聚类分析使用的所有 Delta 写入协议表功能的 Delta 编写器客户端。 在 Azure Databricks 上,必须使用 Databricks Runtime 13.3 LTS 及更高版本。

写入时群集的操作包括:

  • INSERT INTO 操作
  • CTASRTAS 语句
  • Parquet 格式的 COPY INTO
  • spark.write.mode("append")

结构化流式写入始终不会在写入时触发聚类分析。 其他限制适用。 请参阅限制

写入时聚类分析仅在事务中的数据满足大小阈值时触发。 这些阈值因聚类分析列数而异,在 Unity Catalog 托管表中比在其他 Delta 表中更低。

聚类分析列数 Unity Catalog 托管表的阈值大小 其他 Delta 表的阈值大小
1 64 MB 256 MB
2 256 MB 1GB
3 512 MB 2 GB
4 1 GB 4 GB

由于并非所有操作都应用 liquid 聚类分析,因此 Databricks 建议经常运行 OPTIMIZE,以确保有效地聚类分析所有数据。

如何触发聚类分析

若要触发聚类分析,必须使用 Databricks Runtime 13.3 LTS 或更高版本。 对表使用 OPTIMIZE 命令,如以下示例所示:

OPTIMIZE table_name;

Liquid 聚类分析是增量的,这意味着仅在必要时重写数据,以适应需要聚类分析的数据。 若数据文件的聚类分析键与要进行聚类分析的数据不匹配,则数据文件不会重写。

为实现最佳性能,Databricks 建议将常规 OPTIMIZE 作业规划到聚类分析数据。 对于经历多次更新或插入的表,Databricks 建议每隔一或两个小时安排一次 OPTIMIZE 作业。 由于 liquid 聚类分析是增量的,因此聚类分析表的大多数 OPTIMIZE 作业运行速度很快。

从聚类分析表读取数据

可以使用任何支持读取删除向量的 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;

表与 liquid 聚类分析的兼容性

默认情况下,在 Databricks Runtime 14.1 及更高版本中使用 liquid 聚类分析创建的表会使用 v2 检查点。 可以使用 Databricks Runtime 13.3 LTS 及更高版本中的 v2 检查点对表进行读取和写入。

可以禁用 v2 检查点和降级表协议,以读取 Databricks Runtime 12.2 LTS 及更高版本中具有 liquid 聚类分析的表。 请参阅删除 Delta 表功能

限制

存在以下限制:

  • 在 Databricks Runtime 15.1 及更低版本中,写入时聚类分析不支持包含筛选器、联接或聚合的源查询。
  • 结构化流式处理工作负载不支持写入时聚类分析。
  • 无法使用结构化流式写入创建启用了 liquid 聚类分析的表。 可以使用结构化流式处理将数据写入启用了 liquid 聚类分析的现有表。