我的(Py)Spark 2.1.1应用程序包含两个具有5个内核和30G堆(spark.executor.memory
)的执行程序。我有3.2Gb的数据持久保存在十二个分区上的内存中(反序列化),并在我的两个执行器(1.9Gb + 1.3Gb)之间共享。然后,我想通过对持久性数据帧上的repartition('myCol')
调用myCol
来重新分区数据,其中org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle
只有三个键,分布为60-20-20。然后,我想在(3).parquet文件中写入重新分区的数据。不出所料,此转换将触发数据的完全随机播放:
ExecutorLostFailure (executor 2 exited caused by one of the running tasks) Reason: Container killed by YARN for exceeding memory limits. 32.0 GB of 32 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
或spark.yarn.executor.memoryOverhead
之类的错误消息。 2g
已设置为spark.memory.fraction
,但我必须承认,我并没有真正了解此参数在那种情况下应如何提供帮助。但是主要的问题是:如何将30Gb执行器OOM转换为3Gb数据?根据我对Spark的理解,我更改了一些参数(显然成功有限):我将0.9
设置为spark.memory.storageFraction
,将0.0
设置为sed -nE '/^(.)\1/!{/^(.|..)((.)\3+)+$/p}'
。
在此先感谢您的帮助,这种情况令人沮丧。
PS:也许问题解决后,我可以用每个执行者更少的内存来重新设计我的应用程序。目前,这对我来说就像是对资源的极大浪费。