Spark优化“ DataFrame.explain” / Catalyst

时间:2019-09-01 20:11:58

标签: apache-spark optimization internals catalyst-optimizer

我有一个复杂的软件,可以执行非常复杂的SQL查询(不是查询,您知道的Spark计划)。 <-计划是动态的,它们会根据用户输入进行更改,因此我无法“缓存”它们。

我有一个阶段,其中spark需要1.5-2分钟来制定计划。为确保确定,我添加了“ logXXX”,然后说明了(true),然后添加了“ logYYY”,执行说明需要1分20秒。

我正在尝试打破血统,但这似乎会导致性能下降,因为实际执行时间会变长。

我无法并行化驱动程序工作(已经做到了,但是此任务不能与其他任何事情重叠)。

有关如何改善Spark中的计划生成器的任何想法/指南? (例如,尝试启用/禁用的标志等等)

是否可以在Spark中缓存计划? (因此我可以并行运行它,然后执行它)

我尝试禁用所有可能的优化器规则,将最小迭代次数设置为30 ...但是似乎没有什么影响该具体点:S

我尝试禁用了WholeStageCodegen,它有所帮助,但是执行时间更长:)。

谢谢!,

PS:该计划确实包含多个联合(<20,但每个联合内部的计划都很复杂),这是造成时间的原因,但将它们分开也会影响执行时间。

1 个答案:

答案 0 :(得分:0)

以防万一它可以帮助某人(如果没有人提供更多的见解)。

由于我无法设法减少优化器时间(而且,不确定减少优化器时间是否会很好,因为我可能会浪费执行时间)。

我计划的最新部分之一是扫描两个大表,并从每个大表中获取一列(使用Windows,聚合等)。

所以我将代码分为两部分:

1- The big plan (cached)
2- The small plan which scans and aggregates two big tables (cached)

并添加了另一部分:

3- Left Join/enrich the big plan with the output of "2" (this takes like 10seconds, the dataset is not so big) and finish the remainder computation.

现在,我将并行执行两个操作(1,2)(使用驱动程序级并行性/线程),缓存生成的DataFrame,然后再执行3。

有了这个,Spark驱动程序(线程1)正在计算大计划(〜2分钟)时,执行者将执行部分“ 2”(计划虽然小,但是扫描/混洗却很大),然后两者都“混合了” “大约需要10-15秒,这比我在计算计划时节省的1:30更好地缩短了执行时间。

比较时间:

在我拥有之前

1:30 Spark optimizing time + 6 minutes execution time

现在我有

max
(
1:30 Spark Optimizing time + 4 minutes execution time, 
0:02 Spark Optimizing time + 2 minutes execution time
) 
+ 15 seconds joining both parts

不是很多,但是会有很多“昂贵”的人在等它完成:)