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

时间:2015-03-06 14:40:32

标签: apache-spark

我正在以推测模式运行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)

9 个答案:

答案 0 :(得分:39)

当我向工作节点提供的内存比它多时,我发生了这种情况。由于它没有交换,因此在尝试存储用于改组的对象时火花崩溃而没有更多的内存。

解决方案是添加交换,或者将worker / executor配置为使用更少的内存,另外使用MEMORY_AND_DISK存储级别来保留几个持久性。

答案 1 :(得分:14)

我们与Spark有类似的错误,但我不确定它与您的问题有关。

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

答案 2 :(得分:10)

我在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

就是这样!在此之后我的工作顺利完成。

答案 3 :(得分:2)

当特定spark分区中有大量数据时会出现错误。解决这个问题的方法是执行以下步骤:

  1. 增加shuffle-partitions的数量:--conf spark.sql.shuffle.partitions=
  2. 在正常情况下,分区数应设置为执行程序数 * 每个执行程序的核心数。但是如果我们有大量的数据,这种分区方案就会有问题。请参阅下面的示例。

假设我们有以下数据,并且我们有三个执行器,每个执行器有 1 个核心,因此在这种情况下分区(物理分区)的数量为 3

 Data:  1,2,3,4,5,6,7,8,9,13,16,19,22

 Partitions:  1,2,3 
 Distribution of Data in Partitions (partition logic based on modulo by 3)

          1-> 1,4,7,13,16,19,22
          2-> 2,5,8
          3->3,6,9
 From above we can see that there is data skew, partition 1 is having more 
 data than the rest
 
 Now lets increase the number of partitions to : number of executors * number 
 of cores per executor*2 = 6 (in our example. These 6 partitions will be 
 logical partitions.Now each executor will be having 2 logical partitions 
 instead of 1 .Data partitioning will be based on modulo 6 instead of 3.

 Partitions of data in each executor:

        1->(0,1)->1,6,7,13,19
        2->(2,3)-->2,3,8,9
        3->(4,5)->4,5,16,22
The increase in logical partitions leads to fair partitioning.
  1. 在增加shuffle partitions的数量后你可以做的下一件事是 如果你不坚持或减少火花记忆的存储部分 缓存任何数据帧。默认情况下存储部分是 0.5 和执行部分 也是 0.5 。为了减少您可以在 spark-submit 中设置的存储部分 命令如下配置

        --conf spark.memory.storageFraction=0.3
    

4.) 除了以上两件事,您还可以设置执行程序开销内存。 --conf spark.executor.memoryOverhead=2g

 This is off-heap memory that is used for Virtual Machine overheads, interned 
 strings etc.

5.) 除此之外,您还可以限制一次处理的文件数 通过将 maxFilesPerTrigger 设置为较小的特定微批次 值说 10。

答案 4 :(得分:1)

我解决了这个错误,增加了executorMemory和driverMemory中的已分配内存。您可以在HUE中选择导致问题的Spark程序并在属性中执行此操作 - >选项列表可以添加如下内容:

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

当然,参数的值会根据您的群集大小和需求而有所不同。

答案 5 :(得分:1)

对我来说,我正在对大数据(约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%是否与此处提出的问题相同,但这是另一回事。

答案 6 :(得分: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

答案 7 :(得分:0)

在我的情况下(独立群集)引发了异常,因为一些Spark从属文件系统被100%填满。删除从属的spark/work文件夹中的所有内容解决了这个问题。

答案 8 :(得分:0)

我遇到了同样的问题,但是我搜索了许多无法解决我问题的答案。最终,我将逐步调试代码。我发现由数据大小导致的每个分区不均衡的问题导致MetadataFetchFailedExceptionmap阶段而不是reduce阶段。只需在df_rdd.repartition(nums)之前做reduceByKey()