阿里云首页 Databricks数据洞察

自动优化

“自动优化”是一组可选功能,可在每次写入Delta表时自动压缩小文件。在写入过程中支付少量费用可为主动查询的表提供显著的好处。自动优化在以下情况下特别有用:

说明

详细内容可参考Databricks官网文章:自动优化

  • 流式传输用例,可以接受几分钟的延迟

  • MERGE INTO 是写入Delta Lake的首选方法

  • CREATE TABLE AS SELECT或INSERT INTO是常用的操作

自动优化的工作原理

自动优化包含两个补充功能:优化写入和自动压缩。

优化写入

Databricks基于实际数据动态优化Apache Spark分区大小,并尝试为每个表分区写出128 MB文件。这是一个近似大小,并且可能会因数据集特征而异。

自动压缩

每次写入之后,Databricks会检查文件是否可以进一步压缩,并运行一个快速 OPTIMIZE 作业(文件大小为128mb,而不是1GB),以便进一步压缩包含最多小文件的分区的文件。optimized-writes

用法

自动优化旨在针对特定的Delta表进行配置。通过设置table属性delta.autoOptimize.optimizeWrite=true,可以为表启用优化写入。同样地,你设置delta.autoOptimize.autoCompact=true以启用自动压缩。

对于现有表,运行:

SQL

ALTER TABLE [table_name | delta.`<table-path>`] SET TBLPROPERTIES (delta.autoOptimize.optimizeWrite = true, delta.autoOptimize.autoCompact = true)

为确保所有新的Delta表都启用了这些功能,请设置SQL配置:

SQL

set spark.databricks.delta.properties.defaults.autoOptimize.optimizeWrite = true;
set spark.databricks.delta.properties.defaults.autoOptimize.autoCompact = true;

此外,您可以使用以下配置为Spark会话启用和禁用这两个功能:

  • spark.databricks.delta.optimizeWrite.enabled

  • spark.databricks.delta.autoCompact.enabled

session配置优先于表属性,使您可以更好地控制何时选择启用或停用这些功能。

何时选择加入和退出

本节提供有关何时加入和退出自动优化功能的指南。

优化写入 优化写入旨在最大程度地提高写入存储服务的数据吞吐量。这可以通过减少写入的文件数来实现,而不会牺牲太多的并发度。

优化写入要求根据目标表的分区结构来shuffling数据。这种改组自然会招致额外的费用。但是,写入过程中获得的吞吐率收益可以偿还shuffling的成本。如果不是这样,则查询数据时,吞吐量会得到提高。

何时加入

  • 流式传输用例,可以接受几分钟的延迟

  • 当使用诸如MERGE、UPDATE、DELETE、INSERT INTO、createtableasselect等SQL命令时

何时退出

  • 当写入的数据达到TB级时,并且存储优化实例不可用。

  • 当使用spot实例时,spot价格不稳定,导致大部分节点丢失。

自动压缩

自动压缩在成功写入表之后发生,并且在执行写入的集群上同步运行。这意味着,如果你的代码模式向增量 Lake 进行写入,然后立即调用 OPTIMIZE ,则 OPTIMIZE 如果你启用自动压缩,则可以删除该调用。

OPTIMIZE与自动压缩不同。由于它在写入后同步运行,所以我们对自动压缩进行了优化,使其具有以下属性:

  • Databricks不支持带有自动压缩的Z-Ordering,因为Z-Ordering比仅压缩要贵得多。

  • 自动压缩(1 GB)生成较小的OPTIMIZE文件(128 MB)。

  • 自动压缩贪婪地选择一组有限的分区,这些分区最能充分利用压缩。所选分区的数量将根据启动它的集群的大小而变化。如果您的集群有更多的CPU,就可以优化更多的分区。

何时加入

  • 流式使用案例,其中延迟分钟是可接受的

  • 当您的表上没有常规的OPTIMIZE调用时

何时退出

当其他写入程序可能同时执行删除、合并、更新或优化等操作时,因为自动压缩可能会导致这些作业的事务冲突。如果由于事务冲突自动压缩失败,则Databricks不会失败或重试压缩。

工作流程示例:流式引入与并发删除或更新

此工作流假定您有一个集群运行24/7流式处理作业引入数据,另一个集群每小时、每天或临时运行一次以删除或更新一批记录。对于这个用例,Databricks建议您:

  • 在表级别启用Optimized写入,使用

    SQL

    ALTER TABLE <table_name|delta.`table_path`> SET TBLPROPERTIES (delta.autoOptimize.optimizeWrite = true)

    这样可以确保流写入的文件数量以及删除和更新作业的大小都是最佳的。

  • 在执行删除或更新的作业上使用以下设置,在session级别启用“自动压缩”。

    Scala

    spark.sql("set spark.databricks.delta.autoCompact.enabled = true")这样可以在整个表中压缩文件。由于它是在删除或更新之后发生的,因此可以减轻发生事务冲突的风险。

    这样可以在整个表中压缩文件。由于它是在删除或更新之后发生的,因此可以减轻发生事务冲突的风险。

常见问题(FAQ)

是否自动优化Z-Order 文件?

自动优化仅对小文件执行压缩。它不是Z-Order文件。

是否自动优化损坏的Z-Order文件吗?

“自动优化”将忽略Z-Order的文件。它仅压缩新文件。

如果在流式传输的表上启用了“自动优化”,并且并发事务与优化冲突,我的工作会失败吗?

不会。导致自动优化失败的事务冲突将被忽略,并且流式传输将继续正常运行。

OPTIMIZE如果在表上启用了自动优化功能,是否需要计划作业?

对于大小大于10TB的表,我们建议您继续按计划OPTIMIZE运行,以进一步整合文件,并减少Delta表的元数据。由于自动优化不支持 Z-Ordering,所以您仍然应该调度OPTIMIZE...ZORDER BY定期运行作业 。