Spark应用程序杀死执行器

14

我正在独立模式下运行 Spark 集群,应用程序使用 spark-submit。在 Spark UI 的阶段部分中,我发现有一个执行时间很长的执行阶段(> 10h,通常时间为 ~30 sec)。该阶段有许多失败的任务,错误为 Resubmitted (resubmitted due to lost executor)。在阶段页面的聚合度量按执行器部分中,有一个地址为CANNOT FIND ADDRESS的执行器。Spark 会一直尝试重新提交此任务。如果我杀死这个阶段(我的应用程序会自动重新运行未完成的 Spark 作业),所有工作都会继续顺利进行。

此外,我在 Spark 日志中发现了一些奇怪的条目(与阶段开始执行的时间相同)。

Master:

16/11/19 19:04:32 INFO Master: Application app-20161109161724-0045 requests to kill executors: 0
16/11/19 19:04:36 INFO Master: Launching executor app-20161109161724-0045/1 on worker worker-20161108150133
16/11/19 19:05:03 WARN Master: Got status update for unknown executor app-20161109161724-0045/0
16/11/25 10:05:46 INFO Master: Application app-20161109161724-0045 requests to kill executors: 1
16/11/25 10:05:48 INFO Master: Launching executor app-20161109161724-0045/2 on worker worker-20161108150133
16/11/25 10:06:14 WARN Master: Got status update for unknown executor app-20161109161724-0045/1

工作者:

16/11/25 10:06:05 INFO Worker: Asked to kill executor app-20161109161724-0045/1
16/11/25 10:06:08 INFO ExecutorRunner: Runner thread for executor app-20161109161724-0045/1 interrupted
16/11/25 10:06:08 INFO ExecutorRunner: Killing process!
16/11/25 10:06:13 INFO Worker: Executor app-20161109161724-0045/1 finished with state KILLED exitStatus 137
16/11/25 10:06:14 INFO Worker: Asked to launch executor app-20161109161724-0045/2 for app.jar
16/11/25 10:06:17 INFO SecurityManager: Changing view acls to: spark
16/11/25 10:06:17 INFO SecurityManager: Changing modify acls to: spark
16/11/25 10:06:17 INFO SecurityManager: SecurityManager: authentication disabled; ui acls disabled; users with view permissions: Set(spark); users with modify permissions: Set(spark)

由于worker、master(如上面的日志)和driver都在同一台机器上运行,因此网络连接没有问题。

Spark版本1.6.1。


1
你能添加导致问题的工作人员的日志吗?如果任务失败多次,工作人员可能会被终止。是否发生了任何异常情况? - Yuval Itzchakov
@YuvalItzchakov 工作人员登录 POS - 记录了失去执行器的工作人员日志。在执行器丢失之前,没有任何异常和失败。 - Cortwave
"工人登录POS - 工人丢失执行器的日志记录" 我不确定这是什么意思。 - Yuval Itzchakov
@YuvalItzchakov 抱歉,“worker logs in post (my question)”。我在我的问题中添加了工作人员日志。这个工作者失去了执行者。 - Cortwave
@Cortwave,接受答案中的哪个建议对您有用? - vefthym
1
@vefthym 更多的内存分配有所帮助 - Cortwave
2个回答

15

很可能日志中有趣的部分是这个:

16/11/25 10:06:13 INFO Worker: Executor app-20161109161724-0045/1 finished with state KILLED exitStatus 137

Exit 137强烈暗示存在资源问题,可能是内存或CPU核心。鉴于您可以通过重新运行阶段来解决问题,可能是所有核心已经被分配(也许您还在运行某些Spark shell)。这是独立Spark设置(所有内容都在一个主机上)的常见问题。

无论如何,我建议按照以下顺序尝试以下方法:

  1. 提高存储器的内存分配比例spark.storage.memoryFraction,以预先分配更多的存储器,并防止系统OOM Killer在大型阶段中随机给出137
  2. 为应用程序设置较少的核心数,以排除一些在您的阶段运行之前预分配那些核心的可能性。您可以通过spark.deploy.defaultCores进行设置,将其设置为3或甚至2(在英特尔四核假设为8虚拟核心的情况下)
  3. 直接为Spark分配更多的RAM->需要增加spark.executor.memory
  4. 也许您在这里遇到了元数据清理问题,在本地部署中也不是闻所未闻的。在这种情况下,将
    export SPARK_JAVA_OPTS +="-Dspark.kryoserializer.buffer.mb=10 -Dspark.cleaner.ttl=43200"添加到您的spark-env.sh末尾可能会起作用,通过强制运行元数据清理来更频繁地运行。

我认为其中之一应该可以解决问题。


嗨,阿明,你知道在Spark 2.3.x及以后版本中,spark.storage.memoryFraction的等效参数是什么吗?该参数已被弃用。 - user1384205
现在有spark.memory.storageFraction,但是它的效果与传统设置不是1:1可比的。 - Armin Braun

4

阿明的回答非常好。 我只是想指出对我有效的方法。

当我将参数 spark.default.parallelism 从28(即我拥有的执行器数量)增加到84(即可用核心数)时,同样的问题消失了。

注意:这不是设置此参数的规则,这只是对我有效的方法。

更新:这种方法也得到了Spark文档的支持:

有时候,你会收到一个OutOfMemoryError的错误提示,不是因为你的RDD在内存中无法容纳,而是因为你的任务中有一个工作集过大,例如groupByKey中的一个reduce任务。Spark的shuffle操作(sortByKey、groupByKey、reduceByKey、join等)在每个任务中构建哈希表来执行分组,这通常会很大。 最简单的解决办法是增加并行度级别,使每个任务的输入集更小。 Spark可以高效地支持短至200毫秒的任务,因为它在多个任务之间重用一个执行者JVM,并且它具有较低的任务启动成本,因此您可以安全地将并行度级别增加到超过群集中核心数。


你对此有一些理论上的解释吗? - Cortwave
@Cortwave 是的,增加分区数量可以减少每个任务(每个分区由一个任务处理)的内存需求。至于具体的数量,没有固定值,但在我以前的MapReduce经验中,增加更多的分区会产生相同的效果,并且我会不断增加它们,直到不再抛出OOM错误(如果适用)。 - vefthym

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接