SPARK:YARN因超出内存限制而杀死容器

时间:2016-11-21 09:33:29

标签: apache-spark yarn

我们目前遇到的问题是,在YARN上运行时,Spark作业会因为超出内存限制而导致许多容器被杀死。

16/11/18 17:58:52 WARN TaskSetManager: Lost task 53.0 in stage 49.0 (TID 32715, XXXXXXXXXX): 
  ExecutorLostFailure (executor 23 exited caused by one of the running tasks) 
  Reason: Container killed by YARN for exceeding memory limits. 12.4 GB of 12 GB physical memory used. 
    Consider boosting spark.yarn.executor.memoryOverhead.

以下参数通过spark-submit传递:

--executor-memory=6G
--driver-memory=4G
--conf "spark.yarn.executor.memoryOverhead=6G"`

我正在使用Spark 2.0.1。

在阅读有关YARN查杀容器的几篇帖子(例如How to avoid Spark executor from getting lost and yarn container killing it due to memory limit?)之后,我们已将memoryOverhead增加到此值。

鉴于我的参数和日志消息,它似乎“当内存使用量大于(executor-memory + executor.memoryOverhead)时,Yarn会杀死执行程序”。

继续增加这种开销是不切实际的,希望最终我们找到一个不会发生这些错误的值。我们在几个不同的工作中看到了这个问题。我将不胜感激任何关于我应该改变的参数的建议,我应该检查的东西,我应该开始调试这个等等。能够提供进一步的配置选项等。

1 个答案:

答案 0 :(得分:10)

您可以使用spark-defaults.conf中的以下配置减少内存使用量:

spark.default.parallelism
spark.sql.shuffle.partitions

当您为spark.sql.shuffle.partitions使用超过2000个分区时,会有所不同。你可以在Github上的spark代码中看到它:

private[spark] object MapStatus {

  def apply(loc: BlockManagerId, uncompressedSizes: Array[Long]): MapStatus = {
    if (uncompressedSizes.length > 2000) {
      HighlyCompressedMapStatus(loc, uncompressedSizes)
    } else {
      new CompressedMapStatus(loc, uncompressedSizes)
    }
}

我建议尝试使用超过2000个分区进行测试。当你使用非常庞大的数据集时,它可能会更快一些。根据{{​​3}},您的任务可以短至200毫秒。正确的配置不容易找到,但根据您的工作量,它可以产生不同的小时数。