Spark ExecutorLostFailure内存超出

时间:2016-06-03 13:39:59

标签: memory-management apache-spark yarn coalesce

我一直试图获得一个火花工作,现在已经运行完成几天了,我终于能够完成它了但仍然有大量失败的任务,其中执行者被杀死了以下消息:

ExecutorLostFailure(执行者77退出由其中一个正在运行的任务引起)原因:容器被YARN杀死超过内存限制。使用45.1 GB的44.9 GB物理内存。考虑提升spark.yarn.executor.memoryOverhead

这些是我传递给集群的属性:

[
    {
        "classification": "spark-defaults",
        "properties": {
            "spark.executor.memory": "41000m",
            "spark.driver.memory": "8000m",
            "spark.executor.cores": "6",
            "spark.shuffle.service.enabled": "true",
            "spark.executor.instances": "98",
            "spark.yarn.executor.memoryOverhead": "5000"
        }
    }
]

该集群包含20台机器,每台机器有32个内核和240G内存。我是否应该继续提高memoryOverhead,或者是否表明存在更深层次的问题。在将结果数据写入S3之前,此时的错误似乎发生在从5000个分区合并到500个分区期间。我猜测coalesce引起了一次洗牌,因为集群内存已经很低,所以它推得太远了。

工作流程如下:

  1. 将拼版文件从s3加载到数据框
  2. 提取一组唯一键,这些键使用针对dataframe的SQL查询对数据进行分组
  3. 将数据框转换为JavaRDD并应用多个地图函数
  4. MapToPair数据
  5. 使用下面的combineByKey,基本上按键将各个对象合并为对象数组

    combineByKey(新函数,添加函数,合并函数,新HashPartitioner(5000),false,null);

  6. 更多地图

  7. 对于几个唯一键中的每一个,过滤rdd以获得具有该键的元组,然后在合并后将每个子集保留到磁盘
  8. 另一个问题是如何推导出上面的44.9数字。我认为最大内存将是执行程序内存+ memoryOverhead,这将是46G而不是44.9G。

    任何帮助将不胜感激, 内森

1 个答案:

答案 0 :(得分:6)

根据我的经验,这表明存在更深层次的问题,而且从你发布的内容中我发现了一些陷阱。

首先,您可能需要查看分区大小,因为在combineByKey操作期间创建的数据偏差很容易导致OOM。也许有些钥匙非常频繁?

如果没有,我会查看coalesce函数调用。你还没有发布代码,所以我只能猜测正在生成的DAG,但我会知道coalesce函数以及在同一个写阶段执行的其他操作。

Spark分阶段执行,根据我的解释,你可以在coalesce之前调用write,这取决于你进入最后阶段的分区数量,并取决于转换在这个阶段完成,您实际上可能在比所需更少的分区上运行,从而导致OOM异常。

用文字解释有点复杂,但我会尝试举例说明可能发生的事情。

想象一下这样一个简单的场景:你在一个文件中读取了(Int, Double)的键值对,然后你将一些函数应用于所有的值,比如说round。然后,您希望将输出写回单个文件,因此您调用coalesce(1),然后调用write。代码看起来像这样:

val df = sqlContext.read.parquet("/path/to/my/file/")
df.map{case(key: Int, value: Double) => (key, round(value)}
  .toDF()
  .coalesce(1)
  .write
  .parquet("/my/output/path/")

现在有人可能认为map操作是在整个集群上并行执行的,但是如果你注意spark ui,你会注意到这个任务没有在你的集群中分布。由于coalesce(1),Spark知道所有内容都需要在一个分区中结束,所以它只是开始将所有数据收集到应用map函数的一个分区中。正如您可能想象的那样,这很容易在OOM异常中以更复杂的转换结束。

我希望这能为您提供一些关于在哪里寻找的指示。祝你好运:)