增量表文件随着时间的推移会变得碎片化。 碎片会增加文件操作开销,降低压缩效率,并且可能限制读取器的并行度。 压缩将许多小文件重写为较小的文件,以便 Spark 可以更有效地读取和处理数据。
该 OPTIMIZE 命令是主要的压缩操作。 它将小型文件分组到目标的理想文件大小,然后将它们重写存储。
有关跨 SQL Analytics 终结点、Power BI Direct Lake 和 Spark 压缩策略的跨工作负荷指南,请参阅 跨工作负荷表维护和优化。
压缩方法
Microsoft Fabric 提供了几种在 Delta 表中保持最佳文件大小的方法:
OPTIMIZE 命令
该 OPTIMIZE 命令是压缩Delta表的基础操作。 它将小文件重写为较大的文件,以提高 Delta 表中的数据布局。
| 资产 | Description | 默认值 | 会话配置 |
|---|---|---|---|
| minFileSize | 小于此阈值的文件将分组在一起,并重写为较大的文件。 | 1073741824(1克) | spark.databricks.delta.optimize.minFileSize |
| maxFileSize | 命令生成的 OPTIMIZE 目标文件大小。 |
1073741824(1克) | spark.databricks.delta.optimize.maxFileSize |
OPTIMIZE 是幂等的,但过大的 minFileSize 可以增加写入放大。 例如,设置为 minFileSize 1 GB 时,在进行少量额外写入后,可能会重写 900 MB 的文件。 有关自动文件大小管理指南,请参阅 自适应目标文件大小。
OPTIMIZE 与 Z-Order 配合使用
使用 ZORDER BY 子句时,OPTIMIZE 会重新组织活动文件,以便将相似值的行聚合到同一文件中。 这改进了选择性过滤器的文件跳过功能。 在以下情况下使用 Z 顺序:
- 查询经常同时筛选两列或更多列(例如日期 + 客户ID),
- 这些谓词的选择性足够高,使得文件级跳过能够减少扫描的文件数量。
OPTIMIZE dbo.table_name ZORDER BY (column1, column2)
OPTIMIZE 使用 V-Order
该 VORDER 子句将生成作用域为压缩的文件,并应用 V 顺序优化。 有关 V 顺序的详细信息,请参阅详细 文档。
OPTIMIZE dbo.table_name VORDER
OPTIMIZE 使用液体聚类分析
液体聚类分析指定为表选项;有关详细信息,请参阅 启用液体聚类 分析。 启用液体聚类分析后, OPTIMIZE 执行应用聚类分析策略的物理重写。
重要
仅在启用了液体聚集功能的表上运行时,数据才会被聚集。 常规写入作不会对数据进行群集化。 使用压缩策略(例如自动压缩或手动调度优化作业)对于确保能够充分利用集群数据的优势(即增强 Delta 文件的跳过能力)至关重要。
快速优化
快速优化功能可以智能分析 Delta 表文件,并跳过那些不太可能有意义地提高性能的压缩操作。
快速优化会评估每个候选组(小文件组)是否满足可配置的最佳实践压缩目标,而不是盲目地压缩文件。 如果合并文件可能会达到您设定的最小目标大小,或者存在太多小文件,快速优化仅对文件组进行压缩。 否则,它会跳过该组或减少压缩的文件数。
根据您的压缩期望,可以对快速优化进行微调:
| 资产 | Description | 默认值 | 会话配置 |
|---|---|---|---|
| minNumFiles | 如果箱中没有足够的估计数据来生成 压缩 文件,则需要在箱中存在的小型文件数,以便进行优化。 | 50 | spark.microsoft.delta.optimize.fast.minNumFiles |
| parquetCoefficient | 乘以优化上下文最小文件大小,以确定压缩范围内必须存在于箱中的最小小型文件数据量。 | 1.3 | spark.microsoft.delta.optimize.fast.parquetCoefficient |
注释
结果 parquetCoefficient ,箱的目标大小大于优化上下文的最小目标文件大小。 此系数考虑到合并多个小型 parquet 文件可以实现更好的压缩,因此数据量小于小文件的总和。 此值可以增大,以更保守的方式减少快速优化跳过分区的频率,或缩小以允许更宽松的分区跳过。
工作原理
快速优化会在压缩箱之前引入额外的检查。 对于每个候选桶,快速优化进行评估:
- 箱中原始数据的估计量(小文件大小之和)
- 是否估计合并小文件以生成满足配置的最小目标大小的文件
- bin 至少包含配置的最小数量的小文件吗
快速优化会评估每个小型文件箱,并仅压缩可能达到最小目标大小或超过最小文件计数的小文件。 不满足这些阈值的箱将被跳过或部分压缩。 跳过欠佳的 bin 可减少不必要的重写、降低写入放大,并使 OPTIMIZE 作业更具幂等性。
注释
确切的实现可能会随着时间推移而演变。
快速优化可以减少 Delta 表生命周期内重写的数据。 如下图所示,快速优化会跳过欠佳的分区,从而使作业 OPTIMIZE 更加快速且幂等,同时减少写入放大。
注释
出于说明目的,上图假定从压缩写入的文件的大小是小文件的大小之和。 这也意味着 parquetCoefficient 为1。
局限性
- 不适用于液体聚类分析和 Z 顺序操作
- 快速优化不会修改自动压缩的行为
文件级压缩目标
为了避免因更改压缩最小和最大文件大小目标而对先前认为已压缩(足够大)的数据进行重新压缩,可以启用spark.microsoft.delta.optimize.fileLevelTarget.enabled 来防止已压缩文件的重新压缩。 启用后,如果文件在压缩时至少满足目标文件大小的一半,则不会重新编译文件。 维护文件级别的目标可以最大程度地减少写入放大,因为随着时间的推移,压缩目标大小会发生变化(例如,通过计算自适应目标文件大小并设置更大的目标)。 如果启用,当运行 OPTIMIZE 或设置OPTIMIZE_TARGET_SIZE或delta.targetFileSize表属性时,delta.targetFileSize.adaptive标记会被添加到新文件中或在任何写入操作时。
注释
虽然默认情况下未启用,但Microsoft建议启用 文件级压缩目标 以限制潜在的写入放大。
自动压缩
每次写入操作完成后,自动压实都会评估分区健康状况。 当它检测到分区中存在过多文件碎片(太多小文件)时,会在写操作完成后立即触发同步 OPTIMIZE 操作。 这种编写器驱动的文件维护方法是最佳的,因为压缩仅在以编程方式确定有利时执行。
在会话级别启用
在会话级别设置 spark.databricks.delta.autoCompact.enabled ,为在该 Spark 会话中创建的新表启用自动压缩:
在表级别启用
设置表属性 delta.autoOptimize.autoCompact 以启用特定表的自动压缩:
CREATE TABLE dbo.table_name
TBLPROPERTIES ('delta.autoOptimize.autoCompact' = 'true')
使用 DataFrameWriter 选项 delta.autoOptimize.autoCompact 在创建表时启用自动压缩:
df.write.option('delta.autoOptimize.autoCompact', 'true').saveAsTable('dbo.table_name')
对现有表启用相同的表属性:
ALTER TABLE dbo.table_name
SET TBLPROPERTIES ('delta.autoOptimize.autoCompact' = 'true')
优化自动压缩阈值
通过设置以下 Spark 会话配置来优化自动压缩行为:
| 资产 | Description | 默认值 | 会话配置 |
|---|---|---|---|
| maxFileSize | 压缩文件的目标最大文件大小(以字节为单位)。 | 134217728b (128 MB) | spark.databricks.delta.autoCompact.maxFileSize |
| minFileSize | 要视为压缩的文件的最低文件大小(以字节为单位)。 此阈值以下的任何内容都被视为压缩,并计入 minNumFiles 阈值。 |
默认情况下未设置,计算结果为maxFileSize的一半,除非显式设置值。 |
spark.databricks.delta.autoCompact.minFileSize |
| minNumFiles | 在触发自动压缩的阈值下 minFileSize 必须存在的最小文件数。 |
50 | spark.databricks.delta.autoCompact.minNumFiles |
在自动压缩功能和计划优化功能之间进行选择
Microsoft建议自动压缩作为大多数引入工作负荷的默认策略。 它通常优于固定的时间表,并减少维护 OPTIMIZE 作业的运营开销。
如果您的延迟目标非常严格,那么在单独的 Spark 池上进行计划OPTIMIZE可能更合适,因为自动压缩在写入后会同步运行。
将压缩与小型文件防护功能一起使用,例如优化写入。 有关指南,请参阅 “优化写入”。
湖屋表维护
可以从 Lakehouse Explorer 运行即席维护操作,例如 OPTIMIZE。 欲了解更多信息,请参阅 Lakehouse 表维护。
最佳做法摘要
使用这些建议来平衡 Delta 表压缩的写入成本、读取性能和维护开销。
- 为摄取管道启用自动压缩,以应对频繁的小型写入(流式处理或微批处理),从而减少手动调度的需求。
- 当服务级别目标可以容忍偶尔的写入延迟高峰时,将自动压缩选择性地用于其他写入模式。
- 需要重写多个分区或应用 Z-Order 时,在安静时段计划完整表
OPTIMIZE。 -
启用快速优化,可以减少写入放大,并使
OPTIMIZE更具幂等性。 - 启用文件级压缩目标 ,以减少不必要的重新编译,因为目标文件大小随着时间的推移而增加。
- 在合适的引入路径中使用优化写入 ,因为预写入压缩通常比写入后压缩成本更低。 有关指南,请参阅 “优化写入”。