Perché i processi Spark non riescono con org.apache.spark.shuffle.MetadataFetchFailedException: manca un percorso di output per shuffle 0 in modalità speculazione?


88

Sto eseguendo un lavoro Spark con in modalità speculazione. Ho circa 500 attività e circa 500 file compressi da 1 GB gz. Continuo a ricevere in ogni lavoro, per 1-2 attività, l'errore allegato in cui viene ripetuto decine di volte in seguito (impedendo il completamento del lavoro).

org.apache.spark.shuffle.MetadataFetchFailedException: manca una posizione di output per shuffle 0

Qualche idea su quale sia il significato del problema e come risolverlo?

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
Hai visto LostExecutormessaggi INFO? Puoi controllare la pagina degli esecutori dell'interfaccia utente web e vedere come si comportano gli esecutori, esp. Dal punto di vista GC?
Jacek Laskowski

Risposte:


52

Questo è successo a me quando ho dato più memoria al nodo di lavoro di quanta ne abbia. Poiché non aveva lo scambio, Spark si è bloccato durante il tentativo di memorizzare oggetti per mescolare senza più memoria rimasta.

La soluzione era aggiungere lo scambio o configurare il lavoratore / esecutore per utilizzare meno memoria oltre a utilizzare il livello di archiviazione MEMORY_AND_DISK per diversi persist.


3
Se hai una risorsa sul nodo (memoria) puoi provare ad aumentare la memoria dell'esecutore spark. Lo proverò prima se anche tu sei preoccupato per le prestazioni.
nir

15
Ciao @Joren, questa non è una competizione. Il problema dell'OP è che l'esecutore non ha memoria sufficiente per memorizzare l'output casuale. Ciò che ha funzionato per te non è stata la riduzione della memoria dell'esecutore ma l'utilizzo del livello di archiviazione MEMORY_AND_DISK che elimina la limitazione della memoria dell'esecutore. Inoltre OP non dice su quante risorse ha per esecutore.
nir

Ho lo stesso problema e ho provato metodi come aumentare la memoria dell'esecutore, aumentare la quantità di ripartizioni, liberare più memoria fisica. E a volte ha funzionato mentre a volte no. Ho scoperto che questo è accaduto solo in fase di lettura casuale e vorrei chiedere dove posso impostare StorageLevel?
Lhfcws

Ho ottimizzato la mia struttura dati e l'ho risolta. Ho appena cambiato HashMap in un byte [] che è stato serializzato da protostuff
Lhfcws

1
Prova a cambiare spark.driver.overhead.memory e spark.executor.overhead.memory con un valore maggiore di 384 (predefinito) e dovrebbe funzionare. Puoi utilizzare 1024 MB o 2048 MB.
rahul gulati

15

Si è verificato un errore simile con Spark, ma non sono sicuro che sia correlato al tuo problema.

Abbiamo utilizzato JavaPairRDD.repartitionAndSortWithinPartitionsdati da 100 GB e continuava a non funzionare in modo simile alla tua app. Quindi abbiamo esaminato i log di Yarn sui nodi specifici e abbiamo scoperto che abbiamo qualche tipo di problema di memoria insufficiente, quindi Yarn ha interrotto l'esecuzione. La nostra soluzione era quella di cambiamento / add spark.shuffle.memoryFraction 0a .../spark/conf/spark-defaults.conf. Ciò ci ha permesso di gestire una quantità di dati molto maggiore (ma sfortunatamente non infinita) in questo modo.


È davvero "0" o è stato un errore di battitura? Qual è la logica alla base di questo, per costringerlo a riversarsi in modo permanente sul disco?
Virgilio

@Virgil Sì. Abbiamo fatto dei test. Più ci avvicinavamo allo zero maggiore era la quantità processabile. Il prezzo era del 20% del tempo.
elenco

Interessante, ho anche ridotto spark.shuffle.memoryFraction a zero ma ho ricevuto più errori di seguito. (Vale a dire: MetadataFetchFailedException e FetchFailedException a intermittenza) Dovrebbe diventare un bug / problema se "all-spill" ha meno errori di "parzialmente spill".
tribbloide

11

Ho avuto lo stesso problema sul mio cluster YARN a 3 macchine. Ho continuato a cambiare la RAM ma il problema persisteva. Finalmente ho visto i seguenti messaggi nei log:

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

e dopo questo, c'era questo messaggio:

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

Ho modificato le proprietà in spark-defaults.conf come segue:

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

Questo è tutto! Il mio lavoro è stato completato con successo dopo questo.


1
Nella documentazione scintilla, si dice: spark.executor.heartbeatInterval should be significantly less than spark.network.timeout. Quindi, impostare entrambi sullo stesso valore potrebbe non essere l'idea migliore.
Bitswazsky

2

Ho risolto questo errore aumentando la memoria allocata in executorMemory e driverMemory. Puoi farlo in HUE selezionando il programma Spark che sta causando il problema e in Proprietà -> Elenco opzioni puoi aggiungere qualcosa del genere:

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

Ovviamente i valori dei parametri varieranno a seconda delle dimensioni del tuo cluster e delle tue esigenze.


2

Per me, stavo facendo alcune finestre su dati di grandi dimensioni (circa 50 miliardi di righe) e ottenendo un carico della barca di

ExternalAppendOnlyUnsafeRowArray:54 - Raggiunta la soglia di fuoriuscita di 4096 righe, passando a org.apache.spark.util.collection.unsafe.sort.UnsafeExternalSorter

Nei miei log. Ovviamente 4096 può essere piccolo su tali dimensioni di dati ... questo mi ha portato al seguente JIRA:

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

E infine alle seguenti due opzioni di configurazione:

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

Entrambi i valori predefiniti sono 4096; Li ho alzati molto più in alto (2097152) e ora le cose sembrano andare bene. Non sono sicuro al 100% che questo sia lo stesso del problema sollevato qui, ma è un'altra cosa da provare.


1

nell'interfaccia utente Web di Spark, se ci sono alcune informazioni come Executors lost, allora devi controllare il registro del filato, assicurarti che il tuo contenitore sia stato ucciso.

Se il contenitore è stato ucciso, probabilmente è dovuto alla mancanza di memoria.

Come trovare le informazioni chiave nei tronchi di filato? Ad esempio, potrebbero esserci alcuni avvisi come questo:

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

In questo caso, suggerisce di aumentare spark.yarn.executor.memoryOverhead.


0

Nel mio caso (cluster autonomo) l'eccezione è stata lanciata perché il file system di alcuni schiavi Spark era riempito al 100%. L'eliminazione di tutto nelle spark/workcartelle degli schiavi ha risolto il problema.


0

Ho avuto lo stesso problema, ma ho cercato molte risposte che non possono risolvere il mio problema. alla fine, eseguo il debug del mio codice passo dopo passo. Trovo che il problema causato dalla dimensione dei dati non sia bilanciato per ogni partizione, portato a MetadataFetchFailedExceptionquello in mapfase non in reducefase. fallo df_rdd.repartition(nums)primareduceByKey()

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.