Sparkジョブがorg.apache.spark.shuffle.MetadataFetchFailedExceptionで失敗するのはなぜですか:投機モードでシャッフル0の出力場所がありませんか?


85

投機モードでSparkジョブを実行しています。私は約500のタスクと1GBgzの約500のファイルを圧縮しています。私は各ジョブに、1〜2のタスクで、その後数十回再実行される添付エラーを取得し続けます(ジョブが完了しないようにします)。

org.apache.spark.shuffle.MetadataFetchFailedException:シャッフル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 2016

回答:


50

これは、ワーカーノードにそれよりも多くのメモリを与えたときに起こりました。スワップがなかったため、メモリが残っていない状態でシャッフルするオブジェクトを保存しようとしたときに、sparkがクラッシュしました。

解決策は、スワップを追加するか、複数の永続にMEMORY_AND_DISKストレージレベルを使用することに加えて、より少ないメモリを使用するようにワーカー/エグゼキューターを構成することでした。


3
ノード(メモリ)にリソースがある場合は、sparkエグゼキュータのメモリを増やしてみてください。パフォーマンスも気になる場合は、まずそれを試してみます。
nir

14
こんにちは@Jorenこれは競争ではありません。OPの問題は、エグゼキュータにシャッフル出力を格納するのに十分なメモリがないことです。あなたのために働いたのは、エグゼキュータのメモリを減らすことではなく、エグゼキュータのメモリ制限を排除するMEMORY_AND_DISKストレージレベルを使用することです。また、OPは、エグゼキュータのためにどれだけのリソースを持っているかについては述べていません。
nir 2015

私は同じ問題を抱えており、エグゼキュータメモリの増加、再パーティションの量の増加、より多くの物理メモリの解放などの方法を試しました。そして、時にはそれは機能しましたが、時には機能しませんでした。これはシャッフル読み取りフェーズでのみ発生することがわかりました。StorageLevelをどこに設定できるかを尋ねたいのですが。
lhfcws 2017年

データ構造を最適化して修正しました。HashMapをprotostuffによってシリアル化されたbyte []に​​変更しました
Lhfcws

1
spark.driver.overhead.memoryとspark.executor.overhead.memoryを384(デフォルト)より大きい値に変更してみてください。これで動作するはずです。1024MBまたは2048MBのいずれかを使用できます。
rahul gulati 2017

14

Sparkでも同様のエラーが発生しましたが、問題に関連しているかどうかはわかりません。

JavaPairRDD.repartitionAndSortWithinPartitions100GBのデータを使用しましたが、アプリと同様に失敗し続けました。次に、特定のノードのYarnログを調べたところ、何らかのメモリ不足の問題があることがわかったため、Yarnが実行を中断しました。私たちの解決策は、を変更/追加spark.shuffle.memoryFraction 0すること.../spark/conf/spark-defaults.confでした。これにより、この方法ではるかに大量の(ただし、残念ながら無限ではない)データを処理できるようになりました。


それは本当に「0」ですか、それとも入力エラーでしたか?ディスクに永続的に流出させるための、その背後にあるロジックは何ですか?
ウェルギリウス

@Virgilはい。いくつかのテストを行いました。ゼロに近づくほど、処理可能な量が多くなります。価格は時間の20%でした。
Notinlist 2015年

興味深いことに、spark.shuffle.memoryFractionもゼロに減らしましたが、連続してエラーが増えました。(つまり、MetadataFetchFailedExceptionとFetchFailedExceptionが断続的に発生します)「all-spill」のエラーが「partially-spill」よりも少ない場合は、バグ/問題になるはずです。
三倍体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

私の場合、私は大きなデータ(約500億行)でウィンドウ処理を行っており、

ExternalAppendOnlyUnsafeRowArray:54 -4096行の流出しきい値に達し、 org.apache.spark.util.collection.unsafe.sort.UnsafeExternalSorter

私のログに。明らかに、このようなデータサイズでは4096が小さい可能性があります...これにより、次のJIRAが作成されました。

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

そして最終的には次の2つの構成オプションになります。

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

どちらもデフォルトで4096です。私はそれらをはるかに高く上げました(2097152)、そして今はうまくいっているようです。これがここで提起された問題と同じであるかどうかは100%確信できませんが、別の方法で試してみてください。


1

executorMemoryとdriverMemoryに割り当てられたメモリを増やすこのエラーを解決しました。これは、問題の原因となっているSparkプログラムを選択するHUEで行うことができ、プロパティ->オプションリストで次のように追加できます。

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

同じ問題が発生しましたが、問題を解決できない多くの回答を検索しました。最終的に、コードを段階的にデバッグします。データサイズが原因でパーティションごとにバランスが取れていないという問題MetadataFetchFailedExceptionがあり、mapステージではなくreduceステージで問題が発生していることがわかりました。df_rdd.repartition(nums)前にやるreduceByKey()

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.