1

亲爱的 Apache Spark 爱好者

我最近启动了一个副业项目,目标是将几台 ODROID XU4 计算机变成一个独立的 Spark 集群。

设置集群后,我遇到了一个似乎特定于异构多处理器的问题。当使用全部 8 个处理器时,Spark 执行器任务在 XU4 上运行非常缓慢。正如我在下面的帖子的评论中提到的那样,原因是 Spark 不会等待已在慢速处理器上启动的执行程序。

http://forum.odroid.com/viewtopic.php?f=98&t=21369&sid=4276f7dc89a8d7825320e7f705011326&p=152415#p152415

一种解决方案是使用更少的执行器核心并将 CPU 亲和性设置为不使用 LITTLE 处理器。然而,这不是理想的解决方案。

有没有办法让 Spark 等待更长时间以获得较慢执行者的反馈?显然等待太久会对性能产生负面影响。然而,利用所有核心的积极影响应该抵消消极影响。

提前感谢您的帮助!

4

2 回答 2

3

@Dikei 的回应强调了两个潜在的原因,但事实证明问题不是他所怀疑的。我的设置与@TJVR 相同,结果驱动程序缺少执行程序的心跳。为了解决这个问题,我添加了以下内容spark-env.sh

export SPARK_DAEMON_JAVA_OPTS="-Dspark.worker.timeout=600 -Dspark.akka.timeout=200 -Dspark.shuffle.consolidateFiles=true"
export SPARK_JAVA_OPTS="-Dspark.worker.timeout=600 -Dspark.akka.timeout=200 -Dspark.shuffle.consolidateFiles=true"

这会更改执行程序心跳的默认超时。也设置spark.shuffle.consolidateFiles为 true 以提高我的 ext4 文件系统的性能。这些默认值更改使我能够将核心使用量增加到 1 以上,并且不会经常丢失执行程序。

于 2016-07-30T08:55:47.890 回答
1

Spark 不会杀死慢速执行器,但会在两种情况下将执行器标记为已死亡:

  1. 如果驱动程序有一段时间没有收到心跳信号(默认:120s):执行器必须定期(默认:10s)发送心跳消息通知驱动程序它还活着。网络问题或大的 GC 暂停可以阻止这些心跳的发生。

  2. 由于代码中的异常或 JVM 运行时错误,executor 已经崩溃,很可能也是由于 GC 暂停。

在我看来,可能是 GC 开销杀死了你的执行器,驱动程序必须在不同的执行器上重做任务。如果是这种情况,您可以尝试将数据拆分为更小的分区,这样每个 executor 一次必须处理的数据更少。

其次,您不应该spark.speculation在未经测试的情况下设置为“真”。出于某种原因,默认情况下它是“错误的”,我已经看到它在某些情况下弊大于利。

最后,以下假设可能不成立。

然而,利用所有核心的积极影响应该抵消消极影响。

缓慢的执行者(散乱)可能会导致程序执行得更差,具体取决于工作量。完全有可能避免慢速核心将提供最佳结果。

于 2016-07-25T13:02:48.990 回答