我们在AWS EMR上运行Spark Streaming作业。此作业将稳定运行10到14个小时,然后崩溃,在标准错误、标准输出或Cloudwatch日志中没有明显的错误。在此崩溃之后,任何重新启动作业的尝试都会立即失败,并显示"'Cannot allocate memory' (errno=12)"。(完整消息)。
对Cloudwatch指标和Ganglia的调查显示,driver.jvm.heap.used
随着时间的推移稳步增长。
这两个观察结果都让我相信Spark的一些长时间运行的组件(即高于job级别)无法正确释放内存。这是由重新启动hadoop-yarn-resourcemanager(如这里所示)导致堆使用率下降到"新集群"级别所支持的。
如果我的假设确实是正确的-什么会导致Yarn继续消耗越来越多的内存?(如果不是,我怎么能证明呢?)
- 我从这里看到
spark.streaming.unpersist
默认为true(尽管我已经尝试在我的工作结束时添加手动rdd.unpersist()
只是为了检查是否有任何效果-它还没有运行足够长的时间来明确地告诉,然而) - 这里,对
spark.yarn.am.extraJavaOptions
的评论表明,当在Yarn -client模式下运行时(我们是),spark.yarn.am.memory
设置最大Yarn应用程序管理器堆内存使用量。这个值在我们的工作中没有被覆盖(所以应该是默认的512m),但是Cloudwatch和Ganglia都清楚地以gb为单位显示驱动程序堆使用情况。
这里的默认SparkUI值比我们的系统可以处理的大得多。在将它们设置为默认值的1/20之后,系统已经稳定运行了24小时,在此期间堆使用没有增加。
为清楚起见,编辑的值为:
* spark.ui.retainedJobs=50
* spark.ui.retainedStages=50
* spark.ui.retainedTasks=500
* spark.worker.ui.retainedExecutors=50
* spark.worker.ui.retainedDrivers=50
* spark.sql.ui.retainedExecutions=50
* spark.streaming.ui.retainedBatches=50