Apache Spark - 如何避免慢速任务失败
Apache Spark - How to avoid failing slow tasks
亲爱的 Apache Spark 爱好者们
我最近开始了一个副业项目,目标是将几台 ODROID XU4 计算机变成一个独立的 Spark 集群。
设置集群后,我 运行 遇到了一个似乎是异构多处理器特有的问题。使用全部 8 个处理器时,XU4 上的 Spark 执行程序任务 运行 非常慢。正如下面我的 post 的评论中提到的,原因是 Spark 不等待在慢速处理器上启动的执行程序。
一种解决方案是使用较少的执行器核心并将 CPU affinity 设置为不使用 LITTLE 处理器。然而,这是一个不太理想的解决方案。
有没有办法让 Spark 等待更长的时间来等待较慢的执行者的反馈?显然等待时间过长会对性能产生负面影响。然而,利用所有核心的积极影响应该抵消消极影响。
在此先感谢您的帮助!
Spark 不会杀死慢速执行器,但会在两种情况下将执行器标记为已死:
如果driver在一段时间内(默认:120s)没有收到心跳信号:executor必须定时(默认:10s)发送心跳消息通知driver它是还活着。网络问题或大的 GC 暂停可以防止这些心跳发生。
执行程序由于代码异常或 JVM 运行时错误而崩溃,很可能也是由于 GC 暂停。
在我看来,可能是 GC 开销导致你的执行器变慢,驱动程序不得不在不同的执行器上重做任务。如果是这种情况,您可以尝试将您的数据拆分成更小的分区,这样每个执行程序一次处理的数据就会更少。
其次,您不应该在没有测试的情况下将 spark.speculation
设置为 'true'。默认情况下 'false' 是有原因的,我发现它在某些情况下弊大于利。
最后,以下假设可能不成立。
The positive effect of utilising all cores should however balance out
the negative effect.
执行速度慢(掉队)会导致程序性能更差,具体取决于工作量。避免使用慢速内核完全有可能提供最佳结果。
@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 文件系统的性能。这些默认更改使我能够将核心使用率提高到一个以上,并且不会经常丢失执行程序。
亲爱的 Apache Spark 爱好者们
我最近开始了一个副业项目,目标是将几台 ODROID XU4 计算机变成一个独立的 Spark 集群。
设置集群后,我 运行 遇到了一个似乎是异构多处理器特有的问题。使用全部 8 个处理器时,XU4 上的 Spark 执行程序任务 运行 非常慢。正如下面我的 post 的评论中提到的,原因是 Spark 不等待在慢速处理器上启动的执行程序。
一种解决方案是使用较少的执行器核心并将 CPU affinity 设置为不使用 LITTLE 处理器。然而,这是一个不太理想的解决方案。
有没有办法让 Spark 等待更长的时间来等待较慢的执行者的反馈?显然等待时间过长会对性能产生负面影响。然而,利用所有核心的积极影响应该抵消消极影响。
在此先感谢您的帮助!
Spark 不会杀死慢速执行器,但会在两种情况下将执行器标记为已死:
如果driver在一段时间内(默认:120s)没有收到心跳信号:executor必须定时(默认:10s)发送心跳消息通知driver它是还活着。网络问题或大的 GC 暂停可以防止这些心跳发生。
执行程序由于代码异常或 JVM 运行时错误而崩溃,很可能也是由于 GC 暂停。
在我看来,可能是 GC 开销导致你的执行器变慢,驱动程序不得不在不同的执行器上重做任务。如果是这种情况,您可以尝试将您的数据拆分成更小的分区,这样每个执行程序一次处理的数据就会更少。
其次,您不应该在没有测试的情况下将 spark.speculation
设置为 'true'。默认情况下 'false' 是有原因的,我发现它在某些情况下弊大于利。
最后,以下假设可能不成立。
The positive effect of utilising all cores should however balance out the negative effect.
执行速度慢(掉队)会导致程序性能更差,具体取决于工作量。避免使用慢速内核完全有可能提供最佳结果。
@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 文件系统的性能。这些默认更改使我能够将核心使用率提高到一个以上,并且不会经常丢失执行程序。