配置 Delta Lake 以控制数据文件大小

Delta Lake 提供了用于手动或自动配置写入和 OPTIMIZE 操作的目标文件大小的选项。 Azure Databricks 会自动优化其中的许多设置,并启用通过找出适当文件大小来自动提高表性能的功能。

注意

在 Databricks Runtime 13.3 及更高版本中,Databricks 建议对 Delta 表布局使用聚类分析。 请参阅对 Delta 表使用 liquid 聚类分析

Databricks 建议使用预测优化自动运行 OPTIMIZEVACUUM Delta 表。 在 Databricks Runtime 10.4 LTS 及更高版本中,始终为 MERGEUPDATEDELETE 操作启用自动压缩和优化写入。 不能禁用此功能。

除非另有说明,否则本文中的所有建议均不适用于运行最新运行时的 Unity Catalog 托管表。

对于 Unity Catalog 托管表,如果你使用的是 SQL 仓库或 Databricks Runtime 11.3 LTS 或更高版本,则 Databricks 会自动优化其中的大部分配置。

如果要从 Databricks Runtime 11.0 或更低版本升级工作负荷,请参阅升级到后台自动压缩

何时运行 OPTIMIZE

自动压缩和优化写入都可以减少小文件存在的问题,但不能完全替代 OPTIMIZE。 特别是对于大于 1 TB 的表,Databricks 建议按计划运行 OPTIMIZE 以进一步合并文件。 Azure Databricks 不会自动针对表运行 ZORDER,因此你必须结合 ZORDER 运行 OPTIMIZE,以启用增强的数据跳过。 请参阅 Delta Lake 的数据跳过

什么是 Azure Databricks 的自动优化?

术语“自动优化”有时用于描述由设置 delta.autoOptimize.autoCompactdelta.autoOptimize.optimizeWrite 控制的功能。 此术语现已弃用,取而代之的是单独描述每个设置。 请参阅 Azure Databricks 上的 Delta Lake 的自动压缩Azure Databricks 上的 Delta Lake 的优化写入

Azure Databricks 上的 Delta Lake 的自动压缩

自动压缩合并 Delta 表分区中的小文件,以自动减少小文件存在的问题。 自动压缩发生在向表进行写入的操作成功后,在执行了写入操作的群集上同步运行。 自动压缩仅压缩以前尚未压缩过的文件。

可以通过设置 Spark 配置spark.databricks.delta.autoCompact.maxFileSize来控制输出文件大小。 Databricks 建议根据工作负载或表大小使用自动优化。 请参阅根据工作负载自动优化文件大小根据表大小自动优化文件大小

自动压缩仅针对至少具有特定数量的小文件的分区或表触发。 可以选择通过设置 spark.databricks.delta.autoCompact.minNumFiles,来更改触发自动压缩所需的最少文件数。

可以使用以下设置在表或会话级别启用自动压缩:

  • 表属性:delta.autoOptimize.autoCompact
  • SparkSession 设置:spark.databricks.delta.autoCompact.enabled

这些设置接受以下选项:

选项 行为
auto(推荐) 在遵循其他自动优化功能的同时优化目标文件大小。 需要 Databricks Runtime 10.1 或更高版本。
legacy true 的别名。 需要 Databricks Runtime 10.1 或更高版本。
true 使用 128 MB 作为目标文件大小。 不进行动态大小调整。
false 关闭自动压缩。 可以在会话级别设置,以替代工作负载中修改的所有 Delta 表的自动压缩。

重要

在 Databricks Runtime 10.3 及更低版本中,当其他写入者并发执行 DELETEMERGEUPDATEOPTIMIZE 等操作时,自动压缩可能会导致其他作业失败并出现事务冲突。 Databricks Runtime 10.4 及更高版本中不存在此问题。

Azure Databricks 上的 Delta Lake 的优化写入

优化写入在写入数据时改善文件大小,并有利于后续对表的读取。

优化写入对已分区表的效果最好,因为它们可以减少写入每个分区的小文件数。 写入较少的大文件比写入大量的小文件更为有效,但写入延迟仍可能会增加,因为数据在写入之前会随机排列。

下图演示了优化写入的工作原理:

Optimized writes

注意

代码可能在写出数据之前运行 coalesce(n)repartition(n) 以控制写入的文件数。 优化写入消除了对此模式的需要。

默认情况下,为 Databricks Runtime 9.1 LTS 及更高版本中的以下操作启用优化写入:

  • MERGE
  • 使用子查询进行的 UPDATE
  • 使用子查询进行的 DELETE

使用 SQL 仓库时,还会为 CTAS 语句和 INSERT 操作启用优化写入。 在 Databricks Runtime 13.1 及更高版本中,Unity Catalog 中注册的所有 Delta 表都针对分区表的 CTAS 语句和 INSERT 操作启用了优化写入。

可以使用以下设置在表或会话级别启用优化写入:

  • 表设置:delta.autoOptimize.optimizeWrite
  • SparkSession 设置:spark.databricks.delta.optimizeWrite.enabled

这些设置接受以下选项:

选项 行为
true 使用 128 MB 作为目标文件大小。
false 关闭优化写入。 可以在会话级别设置,以替代工作负载中修改的所有 Delta 表的自动压缩。

设置目标文件大小

如果要调整 Delta 表中文件的大小,请将表属性delta.targetFileSize 设置为所需的大小。 如果设置了此属性,所有布局优化操作将尽最大努力生成指定大小的文件。 此处的示例包括优化Z 排序自动压缩优化写入

备注

使用 Unity Catalog 托管表和 SQL 仓库或 Databricks Runtime 11.3 LTS 及更高版本时,只有 OPTIMIZE 命令遵循 targetFileSize 设置。

表属性
delta.targetFileSize

类型:以字节或更大单位计数的大小。

目标文件大小。 例如:104857600(字节)或 100mb

默认值: 无

对于现有表,你可以使用 SQL 命令 ALTER TABLE SET TBL PROPERTIES 设置和取消设置属性。 使用 Spark 会话配置创建新表时,还可以自动设置这些属性。 有关详细信息,请参阅 Delta 表属性参考

根据工作负载自动优化文件大小

Databricks 建议将许多 MERGE 或 DML 操作所针对的所有表的表属性 delta.tuneFileSizesForRewrites 设置为 true,而不管 Databricks Runtime、Unity Catalog 或其他优化设置如何。 设置为 true 后,表的目标文件大小将设置为一个低得多的阈值,从而可以加速写入密集型操作。

如果未显式设置,Azure Databricks 会自动检测最近针对 Delta 表的 10 次操作中,是否有 9 次操作是 MERGE 操作,并将此表属性设置为 true。 必须将此属性显式设置为 false 才能避免此行为。

表属性
delta.tuneFileSizesForRewrites

类型:Boolean

是否调整用于数据布局优化的文件大小。

默认值: 无

对于现有表,你可以使用 SQL 命令 ALTER TABLE SET TBL PROPERTIES 设置和取消设置属性。 使用 Spark 会话配置创建新表时,还可以自动设置这些属性。 有关详细信息,请参阅 Delta 表属性参考

根据表大小自动优化文件大小

为了最大限度地减少手动优化需求,Azure Databricks 会根据表的大小自动调整 Delta 表的文件大小。 Azure Databricks 会对较小的表使用较小的文件大小,对较大的表使用较大的文件大小,以使表中的文件数不会变得过大。 Azure Databricks 不会自动调整你已使用特定目标大小调整的表,也不会根据频繁重写的工作负荷来自动调整表。

目标文件大小基于 Delta 表的当前大小。 对于小于 2.56 TB 的表,自动调整后的目标文件大小为 256 MB。 对于大小介于 2.56 TB 和 10 TB 之间的表,目标大小将从 256 MB 线性增长到 1 GB。 对于大于 10 TB 的表,目标文件大小为 1 GB。

注意

当表的目标文件大小增加时,OPTIMIZE 命令不会将现有文件重新优化为较大的文件。 因此,大型表可能始终具有小于目标大小的某些文件。 如果还需要将这些较小文件优化为较大的文件,则可以使用表属性 delta.targetFileSize 为表配置固定的目标文件大小。

当以增量方式写入表时,根据表大小,目标文件大小和文件计数将大致如下所示。 此表中的文件计数只是一个示例。 实际结果会因许多因素而异。

表大小 目标文件大小 表中的大致文件数
10 GB 256 MB 40
1 TB 256 MB 4096
2.56 TB 256 MB 10240
3 TB 307 MB 12108
5 TB 512 MB 17339
7 TB 716 MB 20784
10 TB 1GB 24437
20 TB 1GB 34437
50 TB 1GB 64437
100 TB 1GB 114437

限制写入数据文件的行数

包含窄数据的表偶尔会遇到这种错误:给定数据文件中的行数超过 Parquet 格式的支持限制。 若要避免此错误,可以使用 SQL 会话配置 spark.sql.files.maxRecordsPerFile 指定要写入 Delta Lake 表的单个文件的最大记录数。 指定零值或负值表示无限制。

在 Databricks Runtime 10.5 及更高版本中,在使用 DataFrame API 写入 Delta Lake 表时,还可以使用 DataFrameWriter 选项 maxRecordsPerFile。 指定后 maxRecordsPerFile,SQL 会话配置 spark.sql.files.maxRecordsPerFile 的值将被忽略。

备注

除非有必要避免上述错误,否则 Databricks 不建议使用此选项。 对于某些包含非常窄的数据的 Unity Catalog 托管表,可能仍有必要使用此设置。

升级到后台自动压缩

后台自动压缩适用于 Databricks Runtime 11.3 LTS 及更高版本中的 Unity Catalog 托管表。 迁移旧工作负荷或表时,请执行以下操作:

  • 从群集或笔记本配置设置中移除 Spark 配置 spark.databricks.delta.autoCompact.enabled
  • 对于每个表,请运行 ALTER TABLE <table_name> UNSET TBLPROPERTIES (delta.autoOptimize.autoCompact) 以移除任何旧自动压缩设置。

移除这些旧配置后,你会看到为所有 Unity Catalog 托管表自动触发的后台自动压缩。