本文介绍 Unity Catalog 外部表的默认分区发现策略和一个可选设置,用于启用分区元数据日志,以使分区发现与 Hive 元存储保持一致。
Databricks 建议启用分区元数据日志记录,以提高具有分区的 Unity Catalog 外部表的读取速度和查询性能。
Unity Catalog 的默认分区发现策略是什么?
默认情况下,Unity Catalog 以递归方式列出表位置中的所有目录,以自动发现分区。 对于具有多个分区目录的大型表,这会增加许多表操作的延迟。
使用分区元数据日志记录
重要
此功能目前以公共预览版提供。
在 Databricks Runtime 13.3 LTS 及更高版本中,可以选择启用分区元数据日志记录,这是注册到 Unity 目录的外部表的分区发现策略。 此行为与 Hive 元存储中使用的分区发现策略一致。 此行为仅影响具有分区并使用 Parquet、ORC、CSV、Avro 或 JSON 的 Unity 目录外部表。 Databricks 建议启用新行为,以提高这些表的读取速度和查询性能。
重要
启用了分区元数据日志记录的表演示了分区发现的行为更改。 Unity Catalog 不会自动扫描表位置以查找分区,而是严格遵守在分区元数据中注册的分区。 请参阅手动添加、删除或修复分区元数据。
此行为将成为未来 Databricks Runtime 版本中的默认值。 启用此功能的表只能使用 Databricks Runtime 13.3 LTS 及更高版本读取或写入。
启用分区元数据日志记录
若要对表启用分区元数据日志记录,请在创建外部表时设置表属性,如以下示例所示:
CREATE OR REPLACE TABLE <catalog>.<schema>.<table-name>
USING <format>
PARTITIONED BY (<partition-column-list>)
TBLPROPERTIES ('partitionMetadataEnabled' = 'true')
LOCATION 'abfss://<bucket-path>/<table-directory>';
创建启用了分区元数据日志记录的表后,Azure Databricks 使用分区元数据读取所有后续工作负荷中的表。
还可以使用 Spark conf 为当前 SparkSession 启用分区元数据。 启用后,将在启用了分区元数据表属性的情况下创建 SparkSession 中创建的外部表。 默认情况下,Spark conf 处于禁用状态。
以下语法演示如何使用 SQL 在笔记本中设置 Spark conf。 还可以在配置计算时设置 Spark 配置。
SET spark.databricks.nonDelta.partitionLog.enabled = true;
可以通过在创建表时显式启用或禁用表属性来替代 Spark conf。
重要
只能在 Databricks Runtime 13.3 LTS 及更高版本中启用分区元数据日志记录的读取和写入表。 若要使用 Databricks Runtime 12.2 LTS 读取这些表,必须删除并重新创建禁用分区元数据表属性的表。
删除外部表时不会删除基础数据文件。 Databricks 建议使用 CREATE OR REPLACE 语法来升级表以使用分区元数据日志记录,如以下示例所示:
CREATE OR REPLACE TABLE <catalog>.<schema>.<table-name>
USING <format>
PARTITIONED BY (<partition-column-list>)
LOCATION 'abfss://<bucket-path>/<table-directory>';
可以通过以下方法检查表是否是使用分区元数据创建的:
- 检查由 DESCRIBE EXTENDED table_name. 返回的表属性节。
- 使用目录资源管理器检查表元数据。
表属性包含 partitionMetadataEnabled=true。
Unity Catalog 对表和卷的路径重叠强制执行规则。 如果某个表已存在于该位置,则无法在数据文件集合中注册新的 Unity Catalog 表。
使用具有分区元数据的表
Databricks 建议对所有已注册到 Unity Catalog 的表使用表名进行所有读取和写入。 对于具有分区元数据的表,这可以保证添加到 Unity Catalog 的表注册的新分区,以及针对表的查询读取所有已注册分区。
对读取或写入使用基于路径的模式可能会导致分区被忽略或未注册到 Unity Catalog 元存储。 请参阅限制。
列出分区
使用以下命令将注册到 Unity Catalog 的所有分区显示为分区元数据:
SHOW PARTITIONS <table-name>
若要检查是否已将单个分区注册到 Unity Catalog,请使用以下命令:
SHOW PARTITIONS <table-name>
PARTITION (<partition-column-name> = <partition-column-value>)
手动添加、删除或修复分区元数据
Unity Catalog 要求外部表的所有分区都包含在表注册期间使用 LOCATION 子句注册的目录中。
启用分区元数据后,将禁用表位置中分区的自动发现。 如果外部系统将数据写入表位置或使用基于路径的写入来添加或覆盖表中的记录,则必须手动修复分区元数据。
Azure Databricks 使用 Hive 样式的分区来存储 Parquet、ORC、CSV 和 JSON 支持的表。 Hive 样式的分区包含通过分区目录中的等号连接的键值对,例如 year=2021/month=01/。
如果表使用 Hive 样式分区,则可以使用 MSCK REPAIR 将 Unity Catalog 中的分区元数据与表位置中存在的分区同步。 以下语法示例演示了常见操作:
-- Add and remove parition metadata to match directories in table location
MSCK REPAIR TABLE <table_name> SYNC PARTITIONS;
-- Add partitions in the table location that are not registered as partition metadata
MSCK REPAIR TABLE <table_name> ADD PARTITIONS;
-- Drop partitions registered as partition metadata that are not in the table location
MSCK REPAIR TABLE <table_name> DROP PARTITIONS;
请参阅 REPAIR TABLE。
手动指定其他分区类型的路径
如果表不使用 Hive 样式分区,则必须在添加分区时手动指定分区位置。 与 MSCK REPAIR 语法相比,手动指定分区还可以降低延迟,尤其是对于具有大量分区的表。 以下语法示例演示如何添加分区:
ALTER TABLE <table-name>
ADD PARTITION (<partition-column-name> = <partition-column-value>)
LOCATION 'abfss://<bucket-path>/<table-directory>/<partition-directory>';
还可以使用 ALTER TABLE 语法删除、重命名、恢复和设置分区的位置。 请参阅更改表分区。
限制
存在以下限制:
- 无法使用 Databricks Runtime 12.2 LTS 或更低版本读取或写入启用了分区元数据的表。
- 使用目录路径读取表将返回所有分区,包括已手动添加或删除的任何分区。
- 如果使用路径而不是表名称在表中插入或覆盖记录,则不会记录分区元数据。
- 不支持 Avro 文件格式。