为什么不使用所有可用执行程序在Spark阶段进行很大的开发?

时间:2019-03-19 16:32:52

标签: apache-spark

我正在执行一些非常大的阶段的Spark任务(例如> 20k个任务),并使用1k到2k的执行程序来运行它。

在某些情况下,一个阶段似乎运行不稳定:随着时间的推移,许多可用的执行器变得闲置,尽管它们仍处于许多未完成任务的中间。从用户的角度看,任务似乎正在完成,但是完成给定任务的执行者不会获得分配给他们的新任务。结果,该阶段花费的时间超过了原本应有的时间,并且空闲时浪费了很多执行器CPU时间。

Spark stderr日志在不稳定时期的示例-请注意,随着时间的流逝,正在运行的任务数量逐渐减少,直到几乎达到零,然后突然跳回> 1k个正在运行的任务:

[Stage 0:==============================>                 (17979 + 1070) / 28504]
[Stage 0:==============================>                 (18042 + 1019) / 28504]
[Stage 0:===============================>                 (18140 + 921) / 28504]
[Stage 0:===============================>                 (18222 + 842) / 28504]
[Stage 0:===============================>                 (18263 + 803) / 28504]
[Stage 0:===============================>                 (18282 + 786) / 28504]
[Stage 0:===============================>                 (18320 + 751) / 28504]
[Stage 0:===============================>                 (18566 + 508) / 28504]
[Stage 0:================================>                (18791 + 284) / 28504]
[Stage 0:================================>                (18897 + 176) / 28504]
[Stage 0:================================>                (18940 + 134) / 28504]
[Stage 0:================================>                (18972 + 107) / 28504]
[Stage 0:=================================>                (19035 + 47) / 28504]
[Stage 0:=================================>                (19067 + 17) / 28504]
[Stage 0:================================>               (19075 + 1070) / 28504]
[Stage 0:================================>               (19107 + 1039) / 28504]
[Stage 0:================================>                (19165 + 982) / 28504]
[Stage 0:=================================>               (19212 + 937) / 28504]
[Stage 0:=================================>               (19251 + 899) / 28504]
[Stage 0:=================================>               (19355 + 831) / 28504]
[Stage 0:=================================>               (19481 + 708) / 28504]

这是阶段稳定运行时stderr的样子-正在运行的任务数量大致保持不变,因为新任务在执行者完成之前的任务时会分配给他们:

[Stage 1:===================>                            (11599 + 2043) / 28504]
[Stage 1:===================>                            (11620 + 2042) / 28504]
[Stage 1:===================>                            (11656 + 2044) / 28504]
[Stage 1:===================>                            (11692 + 2045) / 28504]
[Stage 1:===================>                            (11714 + 2045) / 28504]
[Stage 1:===================>                            (11741 + 2047) / 28504]
[Stage 1:===================>                            (11771 + 2047) / 28504]
[Stage 1:===================>                            (11818 + 2047) / 28504]

在什么情况下会发生这种情况,我该如何避免这种行为?

NB:我正在使用动态分配,但是我很确定这与该问题无关-例如,在不稳定时期,在Spark Application Master UI中,我可以看到预期的执行器数量为“活动” ”,但未运行“活动任务”。

1 个答案:

答案 0 :(得分:1)

当每个任务花费的时间很短时,我从火花中看到了这样的行为。由于某些原因,调度程序似乎认为该作业将完成得更快而没有额外的分发开销,因为每个任务都完成得如此之快。

要尝试的几件事:

  • 尝试使用.coalesce()减少分区数量,以使每个分区都需要更长的运行时间(当然,这可能会导致洗牌,并可能增加总体工作量) 时间,您将不得不试用)
  • 调整spark.locality.wait*设置here。如果每个任务所花费的时间少于默认的等待时间3s,则调度程序可能只是试图保持现有插槽已满,而再也没有机会分配更多的插槽。

我还没有找到确切的原因是什么原因,因此,这些只是基于我对自己(更小)集群的观察得出的推测和预感。