@xtccc
2016-03-18T14:56:49.000000Z
字数 1176
阅读 4674
Spark
运行一个运行时间较长的任务,如下:
val sc = new SparkContext(new SparkConf())
sc.parallelize(Range(0, 1000), 20)
.flatMap(i => for (j <- Range(0, 10000000)) yield (j, i))
.map(x => (x._1+100, x._2-100))
.saveAsTextFile(path)
会发现,控制台输出如下的日志:
有很多executor lost的日志输出。同时,在YARN的页面上查看该Spark app的运行状态,会看到很多executor的“Address”一栏的内容是“CAN NOT FIND ADDRESS”,如下:
分析原因
声明:Spark运行在YARN cluster中,并且开启了 dynamic resource allocation机制。
首先看日志的第2行内容
ExecutorAllocationManager: Removing executor 11 because it has been idle for 60 seconds (new desired total will be 14)
打印日志的class是“org.apache.spark.ExecutorAllocationManager”,可查看源码的注释。
开启了dynamic resource allocation机制后,如果一个executor处于“idle”状态(即executor中没有任何task)的时间超过了设置的阈值(“spark.dynamicAllocation.executorIdleTimeout”),则YARN scheduler会要求释放这个executor。因此,这并不是错误,而是因为这些executors由于已经运行完了,处于idle的时间达到了阈值被YARN killed了而输出的日志。
可以看看ExecutorAllocationManager中的相关代码:
不仅是运行Spark app时会出现“Lost executor”日志,在运行“spark-shell”时也会出现这样的日志。
引申出的问题:
当Spark运行在YARN中时,container与executor的关系是什么样的?
可以认为YARN container与Spark executor是一对一的对应关系。
这个异常与Lost Executor不同,它常常出现在数据量很大,特别是shuffle的数据量很大,或者executor内存比较小时出现,如下
原因一般是:某个task出现了OOM错误,造成JVM的损坏。
需要调整关于内存的参数,例如 spark.yarn.executor.memoryOverhead
参考 这里