Lorsque j'exécute le code d'analyse avec un jeu de données de 1 Go, il se termine sans erreur. Mais, lorsque j'essaie 25 Go de données à la fois, les erreurs sont inférieures à celle-ci. J'essaie de comprendre comment puis-je éviter les échecs ci-dessous. Heureux d'entendre des suggestions ou des idées.
Erreurs differnt,
org.Apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 0
org.Apache.spark.shuffle.FetchFailedException: Failed to connect to ip-xxxxxxxx
org.Apache.spark.shuffle.FetchFailedException: Error in opening FileSegmentManagedBuffer{file=/mnt/yarn/nm/usercache/xxxx/appcache/application_1450751731124_8446/blockmgr-8a7b17b8-f4c3-45e7-aea8-8b0a7481be55/08/shuffle_0_224_0.data, offset=12329181, length=2104094}
Détails du cluster:
Fil: 8 nœuds
Nombre total de noyaux: 64
Mémoire: 500 Go
Version Spark: 1.5
Spark soumettre une déclaration:
spark-submit --master yarn-cluster \
--conf spark.dynamicAllocation.enabled=true \
--conf spark.shuffle.service.enabled=true \
--executor-memory 4g \
--driver-memory 16g \
--num-executors 50 \
--deploy-mode cluster \
--executor-cores 1 \
--class my.parser \
myparser.jar \
-input xxx \
-output xxxx \
Une trace de pile:
at org.Apache.spark.MapOutputTracker$$anonfun$org$Apache$spark$MapOutputTracker$$convertMapStatuses$2.apply(MapOutputTracker.scala:460)
at org.Apache.spark.MapOutputTracker$$anonfun$org$Apache$spark$MapOutputTracker$$convertMapStatuses$2.apply(MapOutputTracker.scala:456)
at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:772)
at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:108)
at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:771)
at org.Apache.spark.MapOutputTracker$.org$Apache$spark$MapOutputTracker$$convertMapStatuses(MapOutputTracker.scala:456)
at org.Apache.spark.MapOutputTracker.getMapSizesByExecutorId(MapOutputTracker.scala:183)
at org.Apache.spark.shuffle.hash.HashShuffleReader.read(HashShuffleReader.scala:47)
at org.Apache.spark.rdd.ShuffledRDD.compute(ShuffledRDD.scala:90)
at org.Apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:297)
at org.Apache.spark.rdd.RDD.iterator(RDD.scala:264)
at org.Apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:38)
at org.Apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:297)
at org.Apache.spark.rdd.RDD.iterator(RDD.scala:264)
at org.Apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)
at org.Apache.spark.scheduler.Task.run(Task.scala:88)
at org.Apache.spark.executor.Executor$TaskRunner.run(Executor.scala:214)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1142)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:617)
at Java.lang.Thread.run(Thread.Java:745)
Cette erreur est presque certainement causée par des problèmes de mémoire sur vos exécuteurs. Je peux penser à deux façons de régler ce type de problèmes.
1) Vous pouvez essayer d’exécuter avec plus de partitions (faites un repartition
sur votre dataframe
). Des problèmes de mémoire surviennent généralement lorsqu'une ou plusieurs partitions contiennent plus de données que la mémoire ne peut en contenir.
2) Je remarque que vous n'avez pas explicitement défini spark.yarn.executor.memoryOverhead
, Donc il utilisera par défaut max(386, 0.10* executorMemory)
qui, dans votre cas, sera de 400 Mo. Cela me semble faible. J'essaierais de l'augmenter à 1 Go (notez que si vous augmentez memoryOverhead à 1 Go, vous devez abaisser --executor-memory
À 3 Go)
3) Recherchez dans les fichiers journaux des nœuds défaillants. Vous voulez chercher le texte "Killing container". Si vous voyez le texte "dépassant les limites de la mémoire physique", augmenter mémoire - sur-tête résoudra - selon mon expérience - le problème.
Outre les problèmes de configuration de la mémoire et du réseau décrits ci-dessus, il convient de noter que pour les tables volumineuses (par exemple, plusieurs TB ici), org.Apache.spark.shuffle.FetchFailedException peut se produire en raison du délai d'attente de récupération Pour résoudre ce problème, vous pouvez définir les éléments suivants:
SET spark.reducer.maxReqsInFlight=1; -- Only pull one file at a time to use full network bandwidth.
SET spark.shuffle.io.retryWait=60s; -- Increase the time to wait while retrieving shuffle partitions before retrying. Longer times are necessary for larger files.
SET spark.shuffle.io.maxRetries=10;
J'ai également obtenu de bons résultats en augmentant le délai d'attente de Spark spark.network.timeout
à une valeur supérieure, telle que 800. Les 120 secondes par défaut provoquent l'expiration d'un grand nombre d'exécuteurs en cas de charge importante.
Ok, c'est un vieux fil et il y a pas mal de réponses sur Stackoverflow, mais j'ai perdu quelques jours à cause de cette erreur et je pense que partager l'histoire pourrait aider.
En fait, cela peut se produire de plusieurs façons. Comme l'a mentionné Glennie dans son excellente réponse, il s'agit probablement d'un problème de mémoire, alors assurez-vous de disposer de suffisamment de mémoire pour tout . Il faut surveiller les configurations de conteneur, de mémoire AM, de mémoire de carte, de mémoire réduite, etc. La lecture this peut être très utile pour trouver les bonnes configurations. Vous devriez choisir les numéros vous-même, mais voici quelques propriétés que j'ai définies.
yarn-site.xml
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>32768</value>
</property>
<property>
<name>yarn.app.mapreduce.am.resource.mb</name>
<value>4096</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>4096</value>
</property>
mapred-site.xml
<property>
<name>mapreduce.map.memory.mb</name>
<value>4096</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>4096</value>
</property>
Celles-ci peuvent corriger d'autres erreurs que vous pourriez rencontrer, telles que le blocage de PySpark Shell au démarrage. Mais dans mon cas, bien que certaines erreurs aient disparu (telles que les erreurs MetadataFetchFailed), le problème a persisté. L'erreur exacte était:
org.Apache.spark.shuffle.FetchFailedException: échec de la connexion à DB-ETA-C/x.x.x.x: 34085
Après avoir joué avec tous les YARN et Spark possibles de Spark du service YARN shuffle), j'ai fini par me rendre compte que le conteneur ayant échoué se trouvait dans le journal des erreurs à la recherche de x.x.x.x
, le IP local (interne) lors de l'exécution de netstat -tulpn | grep <PORT NUM>
a retourné y.y.y.y: 34085 dans lequel y.y.y.y est l’adresse IP external. Ce n'était pas du tout un problème de mémoire, c'était simplement un problème de configuration du réseau.
Le service Spark était lié à l'interface externe uniquement, car le nom d'hôte était associé à l'adresse IP externe dans /etc/hosts
. Après avoir mis à jour le /etc/hosts
fichier le problème a été corrigé.
En bout de ligne: l'erreur indique évidemment qu'un conteneur ne peut pas en atteindre un autre. Cela est généralement dû à l'échec des conteneurs en raison de problèmes de mémoire, mais il peut également s'agir d'un problème de réseau. Surveillez-les également, surtout si vous avez plusieurs interfaces sur vos nœuds.