SPARK:YARN 杀死超过内存限制的容器

SPARK: YARN kills containers for exceeding memory limits

我们目前遇到的问题是,在 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 终止容器的文章后(例如 ),我们已将 memoryOverhead 增加到这个值。

根据我的参数和日志消息,它似乎 "Yarn kills executors when its memory usage is larger than (executor-memory + executor.memoryOverhead)"。

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

您可以在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多个分区进行测试。当您使用非常庞大的数据集时,它有时可能会更快。根据 this,您的任务可以短至 200 毫秒。正确的配置并不容易找到,但根据您的工作量,它可能会有所不同。