我有一个复杂的软件,可以执行非常复杂的SQL查询(不是查询,您知道的Spark计划)。 <-计划是动态的,它们会根据用户输入进行更改,因此我无法“缓存”它们。
我有一个阶段,其中spark需要1.5-2分钟来制定计划。为确保确定,我添加了“ logXXX”,然后说明了(true),然后添加了“ logYYY”,执行说明需要1分20秒。
我正在尝试打破血统,但这似乎会导致性能下降,因为实际执行时间会变长。
我无法并行化驱动程序工作(已经做到了,但是此任务不能与其他任何事情重叠)。
有关如何改善Spark中的计划生成器的任何想法/指南? (例如,尝试启用/禁用的标志等等)
是否可以在Spark中缓存计划? (因此我可以并行运行它,然后执行它)
我尝试禁用所有可能的优化器规则,将最小迭代次数设置为30 ...但是似乎没有什么影响该具体点:S
我尝试禁用了WholeStageCodegen,它有所帮助,但是执行时间更长:)。
谢谢!,
PS:该计划确实包含多个联合(<20,但每个联合内部的计划都很复杂),这是造成时间的原因,但将它们分开也会影响执行时间。
答案 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
不是很多,但是会有很多“昂贵”的人在等它完成:)