我有一个在spark上运行的作业,并使用spark RDD在scala中编写。因为操作昂贵的组我得到这个错误:
Container killed by YARN for exceeding memory limits. 22.4 GB of 22 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead
。
我增加了内存,但我得到了同样的结果。我使用10台r4.xlarge机器。我尝试使用r4.2xlarge甚至r4.4xlarge但同样的错误。我测试的数据是5GB gzip压缩数据(几乎50个解压缩数据和近600万个记录)。
一些配置:
spark.executor.memory
:20480M
spark.driver.memory
:21295M
spark.yarn.executor.memoryOverhead
:2g
spark.executor.instances
:10
代码如下:
val groupedEntitiesRDD = datasetRDD
.groupBy(_.entityId)
.map({ case (key, valueIterator) => key -> valueIterator.toList })
.persist(StorageLevel.MEMORY_AND_DISK)
val deduplicatedRDD = groupedEntitiesRDD
.flatMap({ case (_, entities) => deduplication(entities) })
def deduplication(entities: List[StreamObject[JsValue]]): List[StreamObject[JsValue]] = {
entities
.groupBy(_.deduplicationKey)
.values
.map(duplicates => duplicates.maxBy(_.processingTimestamp.toEpochSecond))
.toList
}
答案 0 :(得分:2)
根据我的经验以及我在Spark 2.x的发行说明中所读到的内容,需要在堆内存(spark.yarn.executor.memoryOverhead
)上分配比Spark 1.x更多的东西。
您只为MemoryOverhead和20GB内存分配了2G。如果你把它改成8G memoryOverhead和14GB执行程序内存,我相信你会得到更好的结果。
如果您仍然遇到内存问题(例如抛出实际的OOM),您将需要查看数据偏差。特别是groupBy
操作经常会导致严重的数据偏差。
最后一件事,你写的是你使用RDDs
- 我希望你的意思是DataFrames
或DataSets
? RDDs
groupBy
的效果非常低(例如,请参阅this博客文章),因此,如果您在RDDs
,则应使用reduceByKey
。但基本上你应该使用DataFrames(或DataSet),其中groupBy
确实是正确的方法。
编辑!
您在评论中询问如何将groupBy
转换为reduceByKey
。你可以这样做:
datasetRDD
.map{case(entityID, streamObject) => (entityID, List(streamObject))}
.reduceByKey(_++_)
.flatMap{case(_, entities) => deduplication(entities)
您还没有指定这些实体的数据结构,但看起来您正在寻找一些最大值,实际上会丢弃不需要的数据。这应该构建到reduceByKey
- 操作中,以便在减少时过滤掉不必要的数据。