【发布时间】:2017-03-11 18:54:24
【问题描述】:
我们在 AWS EMR 上运行 Spark Streaming 作业。该作业将稳定运行 10 到 14 小时,然后在 stderr、stdout 或 Cloudwatch 日志中没有明显错误的情况下崩溃。在这次崩溃之后,任何重新启动作业的尝试都会立即失败,并显示“'Cannot allocate memory' (errno=12)” (full message)。
对 Cloudwatch 指标和 Ganglia 的调查表明,driver.jvm.heap.used 随着时间的推移稳步增长。
这两个观察结果让我相信 Spark 的某些长时间运行的组件(即高于作业级别)未能正确释放内存。重启 hadoop-yarn-resourcemanager(根据here)会导致堆使用率下降到“新集群”级别,这一事实支持这一点。
如果我的假设确实是正确的 - 是什么导致 Yarn 不断消耗越来越多的内存? (如果不是 - 我怎么能伪造呢?)
- 我从here 看到
spark.streaming.unpersist默认为true(尽管我已经尝试在我的工作结束时添加手动rdd.unpersist()以检查这是否有任何影响 - 它还没有运行足够长的时间来确定,但) -
Here,
spark.yarn.am.extraJavaOptions上的评论表明,在 yarn-client 模式下运行时(我们就是这样),spark.yarn.am.memory设置了最大 Yarn Application Manager 堆内存使用量。这个值在我们的工作中没有被覆盖(所以应该是默认值 512m),但是 Cloudwatch 和 Ganglia 都清楚地显示了以千兆字节为单位的驱动程序堆使用情况。
【问题讨论】:
-
您是否偶然进行了有状态流式传输?如果您的状态(保存在内存中)没有得到仔细管理,这可能会导致内存使用量不断增加。我可以告诉你,我们也在 EMR 上运行流式作业,而且它们运行时没有内存问题,所以我怀疑这是你看到的普遍问题......
标签: apache-spark heap-memory spark-streaming hadoop-yarn amazon-emr