为什么Spark作业因org.apache.spark.shuffle.MetadataFetchFailedException而失败:在推测模式下缺少shuffle 0的输出位置?


85

我正在以推测模式运行Spark作业。我有大约500个任务和大约500个1 GB gz压缩文件。我会继续处理每一项工作,执行1-2个任务,然后再执行数十次附加错误(阻止该工作完成)。

org.apache.spark.shuffle.MetadataFetchFailedException:缺少shuffle 0的输出位置

知道这个问题的含义是什么,如何解决?

org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 0
    at org.apache.spark.MapOutputTracker$$anonfun$org$apache$spark$MapOutputTracker$$convertMapStatuses$1.apply(MapOutputTracker.scala:384)
    at org.apache.spark.MapOutputTracker$$anonfun$org$apache$spark$MapOutputTracker$$convertMapStatuses$1.apply(MapOutputTracker.scala:381)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
    at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:108)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:108)
    at org.apache.spark.MapOutputTracker$.org$apache$spark$MapOutputTracker$$convertMapStatuses(MapOutputTracker.scala:380)
    at org.apache.spark.MapOutputTracker.getServerStatuses(MapOutputTracker.scala:176)
    at org.apache.spark.shuffle.hash.BlockStoreShuffleFetcher$.fetch(BlockStoreShuffleFetcher.scala:42)
    at org.apache.spark.shuffle.hash.HashShuffleReader.read(HashShuffleReader.scala:40)
    at org.apache.spark.rdd.ShuffledRDD.compute(ShuffledRDD.scala:92)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:263)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:230)
    at org.apache.spark.rdd.MappedRDD.compute(MappedRDD.scala:31)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:263)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:230)
    at org.apache.spark.rdd.FlatMappedRDD.compute(FlatMappedRDD.scala:33)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:263)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:230)
    at org.apache.spark.rdd.MappedRDD.compute(MappedRDD.scala:31)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:263)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:230)
    at org.apache.spark.rdd.MappedRDD.compute(MappedRDD.scala:31)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:263)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:230)
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:61)
    at org.apache.spark.scheduler.Task.run(Task.scala:56)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:196)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

1
您是否看到任何LostExecutorINFO消息?您能否检查Web UI的“执行程序”页面,并查看执行程序的行为,特别是。GC明智的?
Jacek Laskowski

Answers:


50

当我为工作程序节点提供的内存超过了它的内存时,这发生在我身上。由于没有交换,因此在尝试存储对象以进行改组而没有更多内存时,spark崩溃了。

解决方案是添加交换,或将worker / executor配置为使用更少的内存,此外还使用MEMORY_AND_DISK存储级别进行多个持久化。


3
如果节点(内存)上有资源,则可以尝试增加Spark执行程序的内存。如果您还担心性能,我将首先尝试。
nir

14
嗨,@ Joren,这不是竞赛。OP问题是执行程序没有足够的内存来存储随机播放输出。对您有用的不是减少执行程序的内存,而是使用MEMORY_AND_DISK存储级别,这消除了执行程序的内存限制。OP也没有说他为执行者拥有多少资源。
nir

我有同样的问题,并且尝试了增加执行程序内存,增加分区数量,释放更多物理内存等方法。有时它工作而有时却没有。我发现这仅发生在随机读取阶段,我想问一下在哪里可以设置StorageLevel?
Lhfcws

我优化了数据结构并进行了修复。我只是将HashMap更改为一个由protostuff序列化的byte []
Lhfcws

1
尝试将spark.driver.overhead.memory和spark.executor.overhead.memory的值更改为大于384(默认值)的值,它应该可以工作。您可以使用1024 MB或2048 MB。
rahul gulati

14

我们在Spark中也遇到了类似的错误,但是我不确定这与您的问题有关。

我们使用JavaPairRDD.repartitionAndSortWithinPartitions了100GB的数据,但与您的应用类似,它仍然会失败。然后,我们查看了特定节点上的Yarn日志,发现我们存在某种内存不足的问题,因此Yarn中断了执行。我们的解决方案是修改/添加spark.shuffle.memoryFraction 0.../spark/conf/spark-defaults.conf。这使我们能够以这种方式处理更大(但不幸的是不是无限)的数据量。


是真的“ 0”还是输入错误?强制将其永久溢出到磁盘的背后的逻辑是什么?
维吉尔

@Virgil是的。我们做了一些测试。我们越接近零,可处理量就越大。价格是20%的时间。
Notinlist,2015年

有趣的是,我还将spark.shuffle.memoryFraction减小为零,但连续出现了更多错误。(即:MetadataFetchFailedException和FetchFailedException间歇地)如果“所有溢出”的错误少于“部分溢出”的错误,则该错误/问题。
tribbloid 2015年

11

我在3台机器的YARN群集上遇到了相同的问题。我一直在更换RAM,但是问题仍然存在。最后,我在日志中看到以下消息:

17/02/20 13:11:02 WARN spark.HeartbeatReceiver: Removing executor 2 with no recent heartbeats: 1006275 ms exceeds timeout 1000000 ms
17/02/20 13:11:02 ERROR cluster.YarnScheduler: Lost executor 2 on 1worker.com: Executor heartbeat timed out after 1006275 ms

在此之后,出现此消息:

org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 67

我修改了spark-defaults.conf中的属性,如下所示:

spark.yarn.scheduler.heartbeat.interval-ms 7200000
spark.executor.heartbeatInterval 7200000
spark.network.timeout 7200000

而已!此后,我的工作成功完成。


在spark文档中,它说:spark.executor.heartbeatInterval should be significantly less than spark.network.timeout。因此,将两者设置为相同的值可能不是最好的主意。
Bitswazsky

2

对我来说,我正在对大型数据(约50B行)进行一些窗口处理,并获得了

ExternalAppendOnlyUnsafeRowArray:54 -达到4096行的溢出阈值,切换为 org.apache.spark.util.collection.unsafe.sort.UnsafeExternalSorter

在我的日志中。显然,在这样的数据量上,4096可以很小。这导致我使用了以下JIRA:

https://issues.apache.org/jira/browse/SPARK-21595

最后是以下两个配置选项:

  • spark.sql.windowExec.buffer.spill.threshold
  • spark.sql.windowExec.buffer.in.memory.threshold

两者默认为4096; 我把它们提高了很多(2097152),现在看来情况很好。我不确定100%是否与此处提出的问题相同,但这是另一回事。


1

我解决了此错误,增加了executorMemory和driverMemory中分配的内存。您可以在HUE中选择引起问题的Spark程序来执行此操作,然后在属性->选项列表中添加以下内容:

--driver-memory 10G --executor-memory 10G --num-executors 50 --executor-cores 2

当然,参数的值将根据群集的大小和需求而变化。


1

在Spark Web UI中,如果有诸如之类的信息Executors lost,则您必须检查纱线日志,确保您的容器是否已被杀死。

如果容器被杀死,则可能是由于内存不足。

如何在纱线记录中找到关键信息?例如,可能会有这样的警告:

Container killed by YARN for exceeding memory limits. 2.5 GB of 2.5 GB physical memory used. 
Consider boosting spark.yarn.executor.memoryOverhead.

在这种情况下,建议您增加spark.yarn.executor.memoryOverhead


0

在我的情况下(独立集群),由于某些Spark从站的文件系统已被100%填充而引发了异常。删除spark/work从站文件夹中的所有内容即可解决此问题。


0

我遇到了同样的问题,但是我搜索了许多无法解决我问题的答案。最终,我会逐步调试代码。我发现,造成数据的大小问题不为每个分区平衡,含铅到MetadataFetchFailedExceptionmap阶段不是reduce阶段。就在df_rdd.repartition(nums)之前reduceByKey()

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.