Memory management 已超出Spark Executor LostFailure内存
几天来,我一直在尝试让spark作业运行到完成,我终于能够让它完成,但仍有大量失败的任务,其中执行者被以下消息杀死: ExecutorLostFailure(执行器77因某个正在运行的任务而退出)原因:容器因超出内存限制而被Thread杀死。使用44.9 GB物理内存中的45.1 GB。考虑提升火花.纱线.执行器.内存开销 以下是我要传递给集群的属性:Memory management 已超出Spark Executor LostFailure内存,memory-management,apache-spark,yarn,coalesce,Memory Management,Apache Spark,Yarn,Coalesce,几天来,我一直在尝试让spark作业运行到完成,我终于能够让它完成,但仍有大量失败的任务,其中执行者被以下消息杀死: ExecutorLostFailure(执行器77因某个正在运行的任务而退出)原因:容器因超出内存限制而被Thread杀死。使用44.9 GB物理内存中的45.1 GB。考虑提升火花.纱线.执行器.内存开销 以下是我要传递给集群的属性: [ { "classification": "spark-defaults", "properties"
[
{
"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内存。我应该继续把记忆提高到一个更高的水平,还是有一个更深层次的问题。这次的错误似乎发生在将结果数据写入S3之前从5000个分区合并到500个分区的过程中。我猜合并导致了混乱,因为集群的内存已经不足,所以它把它推得太远了
工作流程如下:
内森根据我的经验,这表明了一个更深层次的问题,从你的帖子中,我看到了几个陷阱 首先,您可能需要查看分区大小,因为OOM很容易由
combineByKey
操作期间创建的数据倾斜引起。也许有些钥匙很常用
如果没有,我将查看coalesce
函数调用。您尚未发布代码,因此我只能猜测正在生成的DAG,但我知道coalesce
函数以及在同一写入阶段执行的其他操作
Spark分阶段执行,从您的解释中我可以看出,您在写入之前调用合并
,因此取决于进入最后阶段的分区数量以及在此阶段中完成的转换,实际上,您操作的分区可能少于所需的分区,从而导致OOM异常
用文字来解释有点复杂,但我将尝试给出一个简单的例子,说明可能发生的情况
想象一下,在一个简单的场景中,您读取一个包含say(Int,Double)
的键值对的文件,然后对所有值应用一些函数,比如sayround
。然后,您希望将输出写回单个文件,因此调用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异常中以更复杂的转换结束
我希望这能给你一些关于去哪里找的建议。祝你好运:)Nathan,你的答案已经贴出来了,你没看到吗?:)太棒了,你提到了分区!