随着 Spark 3.0 的发布,实施了重大改进,使 Spark 的执行速度更快,并附带了许多新功能。其中,动态分区修剪为一体。在深入了解动态分区修剪中新增的功能之前,让我们了解什么是分区修剪。

火花中的分区修剪

在标准数据库修剪中,优化程序将避免读取不能包含要查找的数据的文件。例如,

Sql

 

 
1
from主题"英语"中选择;

在此简单查询中,我们尝试匹配和标识”学生”表中属于主题英语的记录

现在,大多数查询优化器尝试将筛选器从扫描顶部向下推尽可能靠近数据源,以避免扫描完整的数据集。

在分区修剪技术中,它遵循筛选器向下推法,并将数据集进行分区。因为在这种情况下,如果查询具有分区列上的筛选器,则实际上可以跳过完整的分区文件集。

Spark 中的分区修剪是一种性能优化,它限制 Spark 在查询时读取的文件和分区数。分区数据后,匹配某些分区筛选器条件的查询允许 Spark 仅读取目录和文件的子集,从而提高性能。当存在分区筛选器时,催化剂优化器向下推分区筛选器。扫描仅读取与分区筛选器匹配的目录,从而减少磁盘 I/O。

但是,在现实中,数据工程师不仅在查询中执行单个查询或单个筛选器,通常的情况是,他们实际上具有维度表,即他们需要与较大的事实表联接的小表。因此,在这种情况下,我们不能再应用静态分区修剪,因为筛选器位于联接的一侧,而对修剪更具吸引力和更有吸引力的表位于联接的另一侧。所以,我们现在有个问题了。

Sql

 

xxxxxxx
1
 
1
where每日例行公事.主题= "英语";


有些人可能建议我们可以事先将维度表与事实表联接。这样,我们仍然可以在单个表上触发静态修剪。然后,他们可以在单独的查询中执行筛选器,如下所示。

这种方法有明显的缺点,因为首先我们必须执行这个相当昂贵的联接。我们正在复制数据,因为我们必须生成另一个中间表。此表可以非常宽,因为我们采用一堆较小的表,我们将与一张大桌子连接在一起。它不仅很宽,而且在更新维度表时实际上很难管理。因此,每当我们进行更改时,我们实际上必须重新触发整个管道。

在这个博客中,我们将学习一种完全不同的方法,我们将使用动态修剪进行筛选。此优化的基本目标是能够从维度表获取筛选结果。然后直接使用它们来限制我们从事实数据表中获取的数据。

火花中的动态分区修剪

在 Spark SQL 中,用户通常以他们最喜欢的编程语言从他们喜爱的 API 提交查询,因此我们有数据帧和数据集。Spark 采用此查询并将其转换为可消化的形式,我们称之为查询的逻辑计划。在此阶段,Spark 通过应用一组基于规则的转换(如列修剪、恒定折叠、向下推滤镜)来优化逻辑计划。并且只有在以后,它才会得到查询的实际物理规划

在物理规划阶段,火花生成可执行计划。此计划跨许多计算机的群集分配计算。在这里,我将解释如何在逻辑规划级别实现动态分区修剪。然后,我们将研究如何在物理规划期间进一步优化它。

逻辑级别的优化

让我们从逻辑规划级别的优化机会开始。让我们考虑一个跨多个文件分区的数据集。每个分区将因特定颜色而异。相反,我们将有一个较小的表,这是一个不一定分区的维度表。然后,在这些数据集之上,我们拥有典型的扫描运算符因此,当我们完成最终联接操作时,只有这两个分区实际上将被联接保留。

因此,我们不需要实际扫描完整的事实数据表,因为我们只对维度表产生的两个筛选分区感兴趣。为了避免这种情况,一个简单的方法是从集成到子查询中的维度表中获取筛选器。然后在事实表上的扫描下方运行该子查询。

通过这种方式,我们可以发现,当我们计划加入的事实方面。我们能够找出此联接所需的数据。这是一个简单的方法。

但是,它实际上可能很贵。我们需要摆脱这个子查询重复,并找出一种方法,以更有效地做到这一点。为此,我们将了解 Spark 如何在物理规划期间执行联接,以及 Spark 在此物理规划阶段如何转换查询。

物理级别的优化

如果维度表较小,则 Spark 可能会作为广播哈希联接执行联接。每当我们有两个表是哈希联接时,都会发生许多事情:

  1. 首先,Spark 从我们称之为生成关系的维度表中生成哈希表。
  2. 执行此生成关系后,它将将该端的结果插入广播变量。Spark 将该变量分布到参与计算的所有工作人员中。
  3. 通过这样做,我们能够执行联接,而无需洗牌。
  4. 然后,Spark 将开始探测该哈希表,其中包含来自每个辅助角色节点上的事实表的行。

现在,这两个阶段之间显然有一个自然的障碍。因此,首先,我们正在计算联接的广播端。我们正在分发它,只有稍后,我们开始探测和执行实际联接。这很有趣,我们希望能够将这一点用于我们的优化,因为这正是我们与子查询的逻辑规划级别所模仿的。

因此,我们实际上要做的。我们正在拦截生成端的结果 - 广播结果。我们将直接将它们作为动态过滤器插入事实表顶部的扫描仪内。因此,这实际上是一个非常有效和优化的动态分区修剪版本。

结论

总之,在 Apache spark 3.0 中,实现了称为动态分区修剪的新优化,该优化既适用于:

  1. 逻辑规划级别,以查找维度筛选器,并在联接之间传播到扫描的另一侧。
  2. 物理级别以此筛选器仅在尺寸侧执行一次的方式将其连接在一起。
  3. 然后,筛选器的结果直接进入在表的扫描中重用

我希望这个博客是有帮助的。

Comments are closed.