Delta Lake 表优化和 V-Order

LakehouseDelta Lake 表格式是 Microsoft Fabric 的核心,确保针对分析优化表是一项关键要求。 本指南介绍 Delta Lake 表优化概念、配置以及如何将其应用于最常见的大数据使用模式。

什么是 V-Order?

V-Order 是一种针对 Parquet 文件格式的写入时间优化,可以在 Microsoft Fabric 计算引擎(如 Power BI、SQL、Spark 等)下实现快速读取。

Power BI 和 SQL 引擎利用 Microsoft Verti-Scan 技术和经过 V-Order 的 parquet 文件来实现类内存中的数据访问时间。 Spark 和其他非 Verti-Scan 计算引擎也受益于经过 V-Order 的文件,读取时间平均加快 10%,某些方案高达 50%。

V-Order 的工作原理是在 parquet 文件上应用特殊的排序、行组分布、字典编码和压缩,因此在计算引擎中读取它所需的网络、磁盘和 CPU 资源更少,从而提供成本效益和性能。 V-Order 排序对平均写入时间有 15% 的影响,但压缩率最多可增加 50%。

100% 兼容开源 parquet 格式,所有 parquet 引擎都可以将其作为常规 parquet 文件进行读取。 Delta 表比以往更高效,Z-Order 等功能都与 V-Order 兼容。 表属性和优化命令可用于控制其分区上的 V-Order。

V-Order 在 parquet 文件级别应用。 Delta 表及其功能,例如 Z-Order、压缩、清理、按时间顺序查看等,与 V-Order 是正交的,因此它们是兼容的,并且可以配合使用以获得额外的好处。

控制 V-Order 写入

V-Order 在 Microsoft Fabric 中默认启用,在 Apache Spark 中由以下配置控制。

配置 默认值 说明
spark.sql.parquet.vorder.enabled 控制会话级别 V-Order 写入。
TBLPROPERTIES(“delta.parquet.vorder.enabled”) false 表的默认 V-Order 模式
数据帧编写器选项:parquet.vorder.enabled unset 使用数据帧编写器控制 V-Order 写入

使用以下命令控制 V-Order 写入的使用情况。

检查 Apache Spark 会话中的 V-Order 配置

%%sql 
SET spark.sql.parquet.vorder.enabled 

在 Apache Spark 会话中禁用 V-Order 写入

%%sql 
SET spark.sql.parquet.vorder.enabled=FALSE 

在 Apache Spark 会话中启用 V-Order 写入

重要

在会话级别启用时。 所有 parquet 写入都是在启用 V-Order 的情况下进行的。 这包括非 Delta parquet 表和 parquet.vorder.enabled 表属性设置为 truefalse 的 Delta 表。

%%sql 
SET spark.sql.parquet.vorder.enabled=TRUE 

使用 Delta 表属性控制 V-Order

在创建表期间启用 V-Order 表属性:

%%sql 
CREATE TABLE person (id INT, name STRING, age INT) USING parquet TBLPROPERTIES("delta.parquet.vorder.enabled" = "true");

重要

当表属性设置为 true 时,INSERT、UPDATE 和 MERGE 命令将按预期运行并执行写入时优化。 如果 V-Order 会话配置设置为 true 或 spark.write 启用了它,则即使 TBLPROPERTIES 设置为 false,写入操作也将为 V-Order。

通过更改表属性来启用或禁用 V-Order:

%%sql 
ALTER TABLE person SET TBLPROPERTIES("delta.parquet.vorder.enabled" = "true");

ALTER TABLE person SET TBLPROPERTIES("delta.parquet.vorder.enabled" = "false");

ALTER TABLE person UNSET TBLPROPERTIES("delta.parquet.vorder.enabled");

使用表属性启用或禁用 V-Order 后,只会影响将来对表的写入。 Parquet 文件会保留创建时使用的排序。 若要更改当前物理结构以应用或删除 V-Order,请阅读下面的“优化表时控制 V-Order”部分。

直接在写入操作上控制 V-Order

所有 Apache Spark 写入命令都继承会话设置(如果非显式)。 以下所有命令都通过隐式继承会话配置来使用 V-Order 进行写入。

df_source.write\
  .format("delta")\
  .mode("append")\
  .saveAsTable("myschema.mytable")

DeltaTable.createOrReplace(spark)\
  .addColumn("id","INT")\
  .addColumn("firstName","STRING")\
  .addColumn("middleName","STRING")\
  .addColumn("lastName","STRING",comment="surname")\
  .addColumn("birthDate","TIMESTAMP")\
  .location("Files/people")\
  .execute()

df_source.write\
  .format("delta")\
  .mode("overwrite")\
  .option("replaceWhere","start_date >= '2017-01-01' AND end_date <= '2017-01-31'")\
  .saveAsTable("myschema.mytable") 

重要

V-Order 仅适用于受谓词影响的文件。

spark.sql.parquet.vorder.enabled 未设置或设置为 false 的会话中,以下命令将使用 V-Order 进行写入:

df_source.write\
  .format("delta")\
  .mode("overwrite")\
  .option("replaceWhere","start_date >= '2017-01-01' AND end_date <= '2017-01-31'")\
  .option("parquet.vorder.enabled ","true")\
  .saveAsTable("myschema.mytable")

DeltaTable.createOrReplace(spark)\
  .addColumn("id","INT")\
  .addColumn("firstName","STRING")\
  .addColumn("middleName","STRING")\
  .addColumn("lastName","STRING",comment="surname")\
  .addColumn("birthDate","TIMESTAMP")\
  .option("parquet.vorder.enabled","true")\
  .location("Files/people")\
  .execute()

什么是优化写入?

使用标准化的较大文件大小时,Apache Spark 等大数据处理引擎上的分析工作负载执行效率最高。 文件大小、文件数量、Spark 工作器数量及其配置之间的关系对性能起着至关重要的作用。 将数据引入到数据湖表时,可能会继承持续写入大量小文件的特征,这种情况通常被称为“小文件问题”。

优化写入是 Apache Spark 引擎中 Microsoft Fabric 上的 Delta Lake 和 Azure Synapse Analytics 功能,可减少写入的文件数量,并增加写入数据的单个文件大小。 可以使用配置来根据工作负载要求更改目标文件大小。

此功能在 Microsoft Fabric Runtime for Apache Spark 中默认启用。 若要详细了解优化写入使用方案,请阅读文章优化 Apache Spark 上的写入的需求

合并优化

Delta Lake MERGE 命令允许用户使用高级条件更新 Delta 表。 可以使用 MERGE 命令将源表、视图或 DataFrame 中的数据更新到目标表。 但是,Delta Lake 开源版中的当前算法尚未完全针对处理未修改的行进行优化。 Microsoft Spark Delta 团队实现了自定义的 Low Shuffle Merge 优化,未修改的行将从更新匹配行所需的昂贵的随机操作中排除。

该实现由 spark.microsoft.delta.merge.lowShuffle.enabled 配置控制,默认情况下在运行时中启用。 它不需要更改代码,并且与 Delta Lake 的开源版完全兼容。 若要详细了解 Low Shuffle Merge 使用方案,请阅读关于 Delta 表的 Low Shuffle Merge 优化一文。

Delta 表维护

随着 Delta 表的变化,性能和存储成本效率往往会降低,原因如下:

  • 添加到表的新数据可能会扭曲数据。
  • 批处理和流式数据引入速率可能会引入许多小文件。
  • 更新和删除操作最终会产生读取开销,parquet 文件在设计上是不可变的,因此 Delta 表会添加包含变更集的新 parquet 文件,从而进一步放大了前两项造成的问题。
  • 存储中不再需要的数据文件和日志文件。

为了使表保持最佳状态以获得最佳性能,请在 Delta 表中执行箱压缩和清理操作。 箱压缩是通过 OPTIMIZE 命令实现的,它会将所有更改合并为更大的、整合的 parquet 文件。 取消引用的存储清理是通过 VACUUM 命令实现的。

表维护命令 OPTIMIZE 和 VACUUM 可以在笔记本和 Spark 作业定义中使用,然后使用平台功能进行协调。 Fabric 中的湖屋提供了一项功能,可使用用户界面执行特殊表维护,如 Delta Lake 表维护一文中所述。

重要

根据引入频率和预期的读取模式正确设计表物理结构可能比运行本部分所述的优化命令更重要。

优化表时控制 V-Order

以下命令使用 V-Order 构造箱压缩并重写所有受影响的文件,与 TBLPROPERTIES 设置或会话配置设置无关:

%%sql 
OPTIMIZE <table|fileOrFolderPath> VORDER;

OPTIMIZE <table|fileOrFolderPath> WHERE <predicate> VORDER;

OPTIMIZE <table|fileOrFolderPath> WHERE <predicate> [ZORDER  BY (col_name1, col_name2, ...)] VORDER;

当 ZORDER 和 VORDER 一起使用时,Apache Spark 将按顺序执行箱压缩、ZORDER、VORDER。

以下命令使用 TBLPROPERTIES 设置对所有受影响的文件进行箱压缩和重写。 如果 TBLPROPERTIES 设置为 V-Order,则所有受影响的文件都编写为 V-Order。 如果 TBLPROPERTIES 未设置或设置为 V-Order false,那么它将继承会话设置,因此,若要从表中删除 V-Order,请将会话配置设置为 false。

%%sql 
OPTIMIZE <table|fileOrFolderPath>;

OPTIMIZE <table|fileOrFolderPath> WHERE predicate;

OPTIMIZE <table|fileOrFolderPath> WHERE predicate [ZORDER BY (col_name1, col_name2, ...)];