我遇到了一个问题,YARN因为超过内存限制而杀死了我的容器:
Container killed by YARN for exceeding memory limits. physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
我有20个m3.2x大的节点,所以它们有:
cores: 8
memory: 30
storage: 200 gb ebs
我的应用程序的要点是,我有几个10万资产,我有去年每小时生成的历史数据,未压缩的总数据集大小为2TB。我需要使用这些历史数据来生成每个资产的预测。我的设置是,我首先使用s3distcp将存储为索引lzo文件的数据移动到hdfs。然后我提取数据并将其传递给sparkSql以处理json:
val files = sc.newAPIHadoopFile("hdfs:///local/*",
classOf[com.hadoop.mapreduce.LzoTextInputFormat],classOf[org.apache.hadoop.io.LongWritable],
classOf[org.apache.hadoop.io.Text],conf)
val lzoRDD = files.map(_._2.toString)
val data = sqlContext.read.json(lzoRDD)
然后,我使用groupBy按资产对历史数据进行分组,创建一个元组(assetId,timestamp,sparkSqlRow)。我认为,在生成每个资产的预测时,这种数据结构将允许更好的内存操作。
val p = data.map(asset => (asset.getAs[String]("assetId"),asset.getAs[Long]("timestamp"),asset)).groupBy(_._1)
然后,我使用foreach迭代每一行,计算预测,最后将预测作为json文件写回s3。
p.foreach{ asset =>
(1 to dateTimeRange.toStandardHours.getHours).foreach { hour =>
// determine the hour from the previous year
val hourFromPreviousYear = (currentHour + hour.hour) - timeRange
// convert to seconds
val timeToCompare = hourFromPreviousYear.getMillis
val al = asset._2.toList
println(s"Working on asset ${asset._1} for hour $hour with time-to-compare: $timeToCompare")
// calculate the year over year average for the asset
val yoy = calculateYOYforAsset2(al, currentHour, asset._1)
// get the historical data for the asset from the previous year
val pa = asset._2.filter(_._2 == timeToCompare)
.map(row => calculateForecast(yoy, row._3, asset._1, (currentHour + hour.hour).getMillis))
.foreach(json => writeToS3(json, asset._1, (currentHour + hour.hour).getMillis))
}
}
- 有没有更好的方法来实现这一点,这样我就不会遇到YARN的内存问题
- 有没有一种方法可以将资产分块,使foreach一次只能操作约1万笔资产,而不是全部20万笔资产
任何建议/帮助,不胜感激!
这不是您的代码。不要担心foreach
不会同时运行所有这些Lambda。问题是Spark的默认值spark.yarn.executor.memoryOverhead
(或最近在2.3+中重命名为spark.executor.memoryOverhead
)过于保守,这会导致执行器在加载时被杀死。
解决方案是(如错误消息所建议的)增加该值。如果您为每个执行器请求大量内存,我会首先将其设置为1GB(设置为1024
)或更大。目标是让工作在没有任何执行人员被杀的情况下运行。
或者,如果您控制集群,您可以通过在yarn-site.xml
中将配置yarn.nodemanager.pmem-check-enabled
和yarn.nodemanager.vmem-check-enabled
设置为false
来禁用YARN内存强制执行