Fabric 数据工程的本机执行引擎

在 Microsoft Fabric 中,原生执行引擎为 Apache Spark 作业的执行提供了突破性的增强功能。 此矢量化引擎通过直接在 Lakehouse 基础结构上运行 Spark 查询来优化这些查询的性能和效率。 引擎的无缝集成意味着无需修改代码,并可避免供应商锁定。 它支持 Apache Spark API,并与 Runtime 1.3(Apache Spark 3.5) 和 运行时 2.0(Apache Spark 4.1)兼容,并且适用于 Parquet、Delta 和 CSV 格式。 无论数据在 OneLake 中的位置如何,或者是否通过快捷方式访问数据,本机执行引擎都会最大限度地提高效率和性能。

本机执行引擎可显著提升查询性能,同时最大限度地降低运营成本。 实际结果因工作负荷特征和配置而异。 该引擎擅长管理各种数据处理应用场景,从常规数据引入、批处理作业和 ETL(提取、转换、加载)任务到复杂的数据科学分析和响应式交互查询。 用户受益于加速的处理时间、提高的吞吐量和优化的资源利用率。

本机执行引擎基于两个关键 OSS 组件:Velox、Meta 引入的 C++ 数据库加速库和 Apache Gluten (incubating),这是一个中间层,负责将基于 JVM 的 SQL 引擎的执行卸载到 Intel 引入的本机引擎。

支持的运算符从基于 JVM 的 Spark 卸载到矢量化的 C++ 执行路径,提供以列为导向的、通过 SIMD 加速处理的能力,并对 Parquet 和 Delta 格式提供本地支持。 本机引擎保留关键的 Fabric Spark 查询优化功能,包括自适应查询执行(AQE)、基于成本的重写、列修剪和谓词下推,因此在卸载运算符时,这些优化器的行为将保持完全激活。 该引擎还支持并行 Delta 快照加载,并加速在 Delta 表上受益于 Z 排序和液态聚类的操作,从而为有组织的数据布局提供进一步的性能提升。

何时使用本机执行引擎

本机执行引擎提供了一个解决方案,用于在大型数据集上运行查询;其通过使用底层数据源的本机功能来优化性能,并将通常与传统 Spark 环境中的数据移动和序列化相关的开销降到最低。 该引擎支持各种运算符和数据类型,包括汇总哈希聚合、广播嵌套循环联接 (BNLJ) 和精确的时间戳格式。 但是,要充分利用引擎的功能,应考虑其最佳用例:

  • 使用 Parquet 和 Delta 格式的数据时,该引擎能够达到很高的效率,同时可以原生高效地处理这些格式的数据。
  • 涉及复杂转换和聚合的查询可从引擎的列式处理和矢量化功能受益匪浅。
  • 性能增强在查询避免使用不支持的功能或表达式、从而不触发回退机制的场景中最为显著。
  • 该引擎非常适合计算密集型查询,而不是简单或 I/O 绑定查询。

有关本机执行引擎支持的运算符和函数的信息,请参阅 Apache Gluten 文档。

启用本机执行引擎

要在预览阶段使用本机执行引擎的完整功能,需要特定的配置。 以下过程演示如何为笔记本、Spark 作业定义和整个环境激活此功能。

在环境层次启用

为了确保统一性能增强,请在与环境关联的所有作业和笔记本上启用本机执行引擎:

  1. 导航到包含您的环境的工作区,并选择该环境。 如果没有创建环境,请参阅 Fabric 中的创建、配置和使用环境。

  2. 在 Spark 计算 下,选择 “加速”。

  3. 选中标记为“启用本机执行引擎”的框。

  4. 保存并发布更改。

    显示如何在环境项目中启用本机执行引擎的屏幕截图。

在环境级别启用时,所有后续作业和笔记本都会继承该设置。 此继承可确保环境中创建的任何新会话或资源都自动受益于增强的执行功能。

重要

以前,本机执行引擎是通过环境配置中的 Spark 设置启用的。 现在可以使用环境设置的 “加速 ”选项卡中的开关更轻松地启用本机执行引擎。 若要继续使用它,请转到 “加速 ”选项卡并打开切换开关。 如果需要,还可以通过 Spark 属性启用它。

启用用于笔记本或 Spark 作业定义的功能

还可以为单个笔记本或 Spark 作业启用本地执行引擎,必须在执行脚本开始时添加必要的配置:

%%configure 
{ 
   "conf": {
       "spark.native.enabled": "true", 
   } 
} 

对于笔记本,在第一个单元格中插入所需的配置命令。 对于 Spark 作业定义,请在 Spark 作业定义的开头包括配置参数。 本地执行引擎与实时运行池集成,因此启用该功能后,功能会立即发挥作用,而无需启动新会话。

在查询级别控制

在租户、工作区和环境级别上启用本机执行引擎(与 UI 无缝集成)的机制正在积极开发中。 此外,还可以针对特定查询禁用本机执行引擎,特别是涉及当前不支持的运算符时(请参阅限制)。 若要禁用,请将包含该查询的特定单元格的 Spark 配置 spark.native.enabled 设置为 false。

%%sql 
SET spark.native.enabled=FALSE; 

显示如何在笔记本中禁用本机执行引擎的屏幕截图。

执行禁用本机执行引擎的查询后,必须通过将 spark.native.enabled 设置为 true 为后续单元格重新启用它。 此步骤是必需的,因为 Spark 按顺序执行代码单元。

%%sql 
SET spark.native.enabled=TRUE; 

识别引擎执行的操作

有多种方法可确定 Apache Spark 作业中的运算符是否使用本机执行引擎进行处理。

Spark UI 和 Spark 历史记录服务器

访问 Spark UI 或 Spark 历史记录服务器以找到需要检查的查询。 要访问 Spark 网页界面,请进入你的 Spark 作业定义并运行它。 在“运行”选项卡中,选择在 应用程序名称 旁边的“...”,然后选择 打开 Spark Web UI。 还可以从工作区中的“监视”选项卡访问 Spark UI。 从监视页中选择笔记本或管道,会出现指向活动作业 Spark UI 的直接链接。

显示如何导航到 Spark Web UI 的屏幕截图。

在 Spark UI 界面中显示的查询计划中,查找以 Transformer、*NativeFileScan 或 VeloxColumnarToRowExec作为后缀结尾的任何节点名称。 该后缀表示本机执行引擎执行了该操作。 例如,节点可能标记为 RollUpHashAggregateTransformer、ProjectExecTransformer、BroadcastHashJoinExecTransformer、ShuffledHashJoinExecTransformer 或 BroadcastNestedLoopJoinExecTransformer。 对于 CSV 数据源,原生扫描可能会在 Spark UI 中显示为原生文件扫描或转换节点,类似于 Parquet 和 Delta 扫描节点。

显示如何检查以后缀 Transformer 结尾的 DAG 可视化效果的屏幕截图。

DataFrame 说明

或者,可以在笔记本中执行 df.explain() 命令以查看执行计划。 在输出中,查找相同的“Transformer”、“*NativeFileScan”或“VeloxColumnarToRowExec”后缀。 此方法可快速确认是否由本机执行引擎处理特定操作。

显示如何检查查询的物理计划,并查看查询是否由本机执行引擎执行的屏幕截图。

Fabric Spark 顾问警报

Fabric Spark 顾问在笔记本单元执行期间提供实时回退可见性。 当操作符或计划段回退到基于 JVM 的 Spark 而不是本机路径时,Advisor 会在笔记本单元输出中直接显示警报,帮助你快速识别不受支持的操作符或配置,无需离开笔记本即可。 可以使用这些警报来诊断未应用本机卸载时,以及决定是否调整查询或配置。

回退机制

在某些情况下,本机执行引擎可能由于不支持的功能等原因而无法执行查询。 在这些情况下,该操作会回退到传统的 Spark 引擎。 此自动回退机制可确保工作流不会中断。

显示回退机制的屏幕截图。

显示如何查看与回退机制关联的日志的屏幕截图。

监控引擎执行的查询和数据帧

为了更好地了解本机执行引擎如何应用于 SQL 查询和 DataFrame 操作,以及向下钻取到阶段和运算符级别,可以参考 Spark UI 和 Spark 历史记录服务器了解有关本机引擎执行的详细信息。

本机执行引擎选项卡

可以导航到新的“Gluten SQL/DataFrame”选项卡,查看 Gluten 生成信息和查询执行详细信息。 查询表提供有关本机引擎上运行的节点数以及每个查询回退到 JVM 的节点数的见解。

显示本机执行引擎选项卡的屏幕截图。

查询执行图

您还可以选择查询说明以进行 Apache Spark 查询执行计划的可视化。 执行图提供有关不同阶段及其各自操作的本地执行详细信息。 背景色区分执行引擎:绿色表示本机执行引擎,而浅蓝色表示操作在默认 JVM 引擎上运行。

显示查询执行图的屏幕截图。

限制

虽然 Fabric 中的原生执行引擎(NEE)显著提升了 Apache Spark 作业的性能,但目前存在以下限制。 适用于 运行时 1.3(Apache Spark 3.5 )的若干正确性相关事项在 运行时 2.0(Apache Spark 4.1)中得到解决;每个项目都标注其适用的运行时间。

现有限制

  • 不兼容的 Spark 功能 (所有运行时):本地执行引擎目前不支持结构化流。 如果你直接使用不支持的功能,或者通过导入库,Spark 会恢复到默认引擎。 原生执行引擎现在支持 Python UDF、Scala UDF 以及复杂的数据类型(数组、映射、结构体)。 有关详细信息,请参阅本机执行引擎中的 Python UDF、Scala UDF 和复杂数据类型。

  • 不支持的文件格式 (所有运行时):本地执行引擎不加速针对 JSON 和 XML 格式的查询。 这些格式默认回到常规的 Spark JVM 引擎执行。 矢量化的CSV解析器现在支持CSV。

  • ANSI 模式 (仅运行时 1.3):在运行时 1.3(Apache Spark 3.5)中,原生执行引擎不支持 ANSI SQL 模式。 如果你启用了ANSI SQL模式,执行会回退到原版Spark引擎。 在运行时 2.0(Apache Spark 4.1)中,支持 ANSI SQL 模式:操作符卸载到本地引擎,且 ANSI 错误语义(例如除以零和无效投射)通过 JVM Spark 一致执行。

  • 日期过滤类型不匹配 (所有运行时):为了利用本地执行引擎的加速,确保日期比较的两侧数据类型一致。 例如,不要将DATETIME列与字符串文本进行比较,而要按如下所示显式转换:

    CAST(order_date AS DATE) = '2024-05-20'
    

其他注意事项和限制

注释

本节中的十进制投射、时区、round()重复map()键和collect_list()collect_set()/项目适用于运行时1.3(Apache Spark 3.5),并在运行时2.0(Apache Spark 4.1)中解析。 它们保留给仍在运行运行时1.3的用户。

  • 十进制到浮点数的铸造不匹配(运行时 1.3;运行时 2.0 解决):当从 DECIMAL 到 FLOAT铸造时,Spark 通过转换为字符串并解析来保持精度。 在运行时1.3中,NEE(通过Velox)直接从内部 int128_t 表示中进行投射,这可能导致舍入差异。

  • 时区配置错误 (运行时 1.3;运行时 2.0 解决):在运行时 1.3 中,在 Spark 设置未识别的时区会导致作业在 NEE 下失败,而 Spark JVM 则能优雅地处理。 例如:

    "spark.sql.session.timeZone": "-08:00"  // May cause failure under NEE on Runtime 1.3
    
  • 不一致的舍入行为 (运行时 1.3;运行时 2.0 解决):在运行时 1.3 中, round() 函数在 NEE 中表现不同,因为 std::round依赖 ,而 无法复制 Spark 的舍入逻辑。 这种差异可能导致四舍五入结果的数值不一致。

  • 函数中缺少重复密钥检查map()(运行时 1.3;运行时 2.0 解决):当 spark.sql.mapKeyDedupPolicy 设置为 EXCEPTION 时,Spark 会因重复密钥而报错。 在运行时1.3中,NEE跳过了这一检查,允许查询错误成功。 在运行时2.0,NEE与JVM Spark的加注 DUPLICATED_MAP_KEY 稳定。
    示例:

    SELECT map(1, 'a', 1, 'b'); -- Should fail with duplicate keys
    
  • 在排序时的 collect_list() 顺序差异 (运行时1.3;在运行时2.0中解决):当使用 DISTRIBUTE BY 和 SORT BY时,Spark保持元素的 collect_list()顺序。 在运行时1.3中,NEE可能因洗牌差异返回的值顺序不同,这可能导致对顺序敏感逻辑的期望不匹配。

  • 中间collect_list() / collect_set()类型不匹配(运行时 1.3;在运行时 2.0 中解析):在运行时 1.3 中,Spark 作为BINARY这些聚合的中间类型,而 NEE 使用 ARRAY。 这种不匹配可能会导致查询规划或执行期间出现兼容性问题。

  • 存储访问所需的托管私有端点(所有运行时):当启用原生执行引擎(NEE)时,如果火花作业试图通过托管私有端点访问存储账户,你必须为Blob(blob.core.windows.net)和DFS / File System(dfs.core.windows.net)端点分别配置管理私有端点,即使它们指向同一个存储账户。 你不能同时用一个端点来做两者。 当该限制在拥有托管私有端点到存储账户的工作区启用本地执行引擎时,可能需要额外的网络配置。