web-dev-qa-db-fra.com

La taille totale des résultats sérialisés de 16 tâches (1048,5 Mo) est plus grande que spark.driver.maxResultSize (1024,0 Mo)

J'obtiens l'erreur suivante lorsque j'ajoute --conf spark.driver.maxResultSize=2050 à mon spark-submit commande.

17/12/27 18:33:19 ERROR TransportResponseHandler: Still have 1 requests outstanding when connection from /XXX.XX.XXX.XX:36245 is closed
17/12/27 18:33:19 WARN Executor: Issue communicating with driver in heartbeater
org.Apache.spark.SparkException: Exception thrown in awaitResult:
        at org.Apache.spark.util.ThreadUtils$.awaitResult(ThreadUtils.scala:205)
        at org.Apache.spark.rpc.RpcTimeout.awaitResult(RpcTimeout.scala:75)
        at org.Apache.spark.rpc.RpcEndpointRef.askSync(RpcEndpointRef.scala:92)
        at org.Apache.spark.executor.Executor.org$Apache$spark$executor$Executor$$reportHeartBeat(Executor.scala:726)
        at org.Apache.spark.executor.Executor$$anon$2$$anonfun$run$1.apply$mcV$sp(Executor.scala:755)
        at org.Apache.spark.executor.Executor$$anon$2$$anonfun$run$1.apply(Executor.scala:755)
        at org.Apache.spark.executor.Executor$$anon$2$$anonfun$run$1.apply(Executor.scala:755)
        at org.Apache.spark.util.Utils$.logUncaughtExceptions(Utils.scala:1954)
        at org.Apache.spark.executor.Executor$$anon$2.run(Executor.scala:755)
        at Java.util.concurrent.Executors$RunnableAdapter.call(Executors.Java:511)
        at Java.util.concurrent.FutureTask.runAndReset(FutureTask.Java:308)
        at Java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.Java:180)
        at Java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.Java:294)
        at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1149)
        at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:624)
        at Java.lang.Thread.run(Thread.Java:748)
Caused by: Java.io.IOException: Connection from /XXX.XX.XXX.XX:36245 closed
        at org.Apache.spark.network.client.TransportResponseHandler.channelInactive(TransportResponseHandler.Java:146)

La raison de l'ajout de cette configuration était l'erreur:

py4j.protocol.Py4JJavaError: An error occurred while calling o171.collectToPython.
: org.Apache.spark.SparkException: Job aborted due to stage failure: Total size of serialized results of 16 tasks (1048.5 MB) is bigger than spark.driver.maxResultSize (1024.0 MB)

Par conséquent, j'ai augmenté maxResultSize à 2,5 Go, mais le travail Spark échoue quand même (l'erreur indiquée ci-dessus). Comment résoudre ce problème?

10
Markus

Il semble que le problème soit que la quantité de données que vous essayez de récupérer vers votre pilote soit trop grande. Vous utilisez probablement la méthode collect pour récupérer toutes les valeurs d'un DataFrame/RDD . Le pilote est un processus unique et en collectant un DataFrame vous tirez toutes ces données que vous aviez réparties sur le cluster vers un nœud. Cela va à l'encontre du but de le distribuer! Cela n'a de sens que lorsque vous avez réduit les données à un niveau gérable.

Vous avez deux options:

  1. Si vous avez vraiment besoin de travailler avec toutes ces données, vous devez les garder à l'écart des exécuteurs. Utilisez [~ # ~] hdfs [~ # ~] et Parquet pour enregistrer les données de manière distribuée et utiliser les méthodes Spark pour travailler avec les données sur le cluster au lieu d'essayer de les rassembler en un seul endroit.

  2. Si vous avez vraiment besoin de renvoyer les données au pilote, vous devez déterminer si vous avez vraiment besoin de TOUTES les données ou non. Si vous n'avez besoin que de statistiques récapitulatives, calculez-les sur les exécuteurs avant d'appeler collect. Ou si vous n'avez besoin que des 100 premiers résultats, alors seulement collectez les 100 premiers.

Mise à jour:

Il existe une autre raison pour laquelle vous pouvez rencontrer cette erreur qui est moins évidente. Spark essaiera de renvoyer les données au-delà du pilote juste au moment où vous appelez explicitement collect. Il renverra également les résultats de l'accumulateur pour chaque tâche si vous utilisez des accumulateurs, des données pour les jointures de diffusion et quelques petites données d'état sur chaque tâche. Si vous avez BEAUCOUP de partitions (20k + selon mon expérience), vous pouvez parfois voir cette erreur. Il s'agit d'un problème conn avec quelques améliorations apportées, et plus dans le fonctionne .

Les options pour passer si si c'est votre problème sont les suivantes:

  1. Augmenter spark.driver.maxResultSize ou définissez-le sur 0 pour un nombre illimité
  2. Si les jointures de diffusion sont le coupable, vous pouvez réduire spark.sql.autoBroadcastJoinThreshold pour limiter la taille des données de jointure de diffusion
  3. Réduisez le nombre de partitions
17
Ryan Widmaier

Cause: causée par des actions comme collect () de RDD qui envoient un gros morceau de données au pilote

Solution: définie par SparkConf: conf.set("spark.driver.maxResultSize", "4g") OR définie par spark-defaults.conf: spark.driver.maxResultSize 4g OR défini lors de l'appel de spark-submit: --conf spark.driver.maxResultSize=4g

0
vj sreenivasan