Comment résoudre les erreurs « Container killed on request. Exit code is 137 » (Conteneur supprimé sur demande. Le code de sortie est 137) dans Spark sur Amazon EMR ?

Dernière mise à jour : 08/01/2020

Ma tâche Apache Spark sur Amazon EMR échoue avec le message « Container killed on request » :

Caused by: org.apache.spark.SparkException: Job aborted due to stage failure: Task 2 in stage 3.0 failed 4 times, most recent failure: Lost task 2.3 in stage 3.0 (TID 23, ip-xxx-xxx-xx-xxx.compute.internal, executor 4): ExecutorLostFailure (executor 4 exited caused by one of the running tasks) Reason: Container marked as failed: container_1516900607498_6585_01_000008 on host: ip-xxx-xxx-xx-xxx.compute.internal. Exit status: 137. Diagnostics: Container killed on request. Exit code is 137

Brève description

Lorsqu'un conteneur (programme d'exécution Spark) manque de mémoire, YARN le supprime automatiquement. Cela entraîne le message d'erreur « Container killed on request. Exit code is 137 » (Conteneur supprimé sur demande. Le code de sortie est 137). Ces erreurs peuvent se produire à différentes étapes de la tâche, à la fois dans des transformations étroites et étendues.

Solution

Utilisez une ou plusieurs des méthodes suivantes pour résoudre les messages d'erreur « Exit status : 137 » :

Augmentez la mémoire du pilote et de l'exécuteur

Augmentez la mémoire du conteneur en ajustant les paramètres spark.executor.memory ou spark.driver.memory (en fonction du conteneur à l'origine de l'erreur).

Sur un cluster en cours d'exécution :

Modifiez spark-defaults.conf sur le nœud principal. Exemple :

sudo vim /etc/spark/conf/spark-defaults.conf
spark.executor.memory 10g
spark.driver.memory 10g

Pour une seule tâche :

Utilisez les options --executor-memory ou --driver-memory pour augmenter la mémoire lorsque vous exécutez spark-submit. Exemple :

spark-submit --executor-memory 10g --driver-memory 10g ...

Ajouter d'autres partitions Spark

Si vous ne pouvez pas augmenter la mémoire du conteneur (par exemple, si vous utilisez maximizeResourceAllocation sur le nœud), augmentez le nombre de partitions Spark. Cette méthode permet de réduire la quantité de données traitées par une seule tâche Spark, réduisant ainsi la mémoire globale utilisée par un seul programme d'exécution. Utilisez le code Scala suivant pour ajouter d'autres partitions Spark :

val numPartitions = 500
val newDF = df.repartition(numPartitions)

Augmenter le nombre de partitions aléatoire

Si l'erreur se produit pendant une transformation étendue (par exemple, join ou groupBy), ajoutez d'autres partitions aléatoires. La valeur par défaut est 200.

Sur un cluster en cours d'exécution :

Modifiez spark-defaults.conf sur le nœud principal. Exemple :

sudo vim /etc/spark/conf/spark-defaults.conf
spark.sql.shuffle.partitions 500

Pour une seule tâche :

Utilisez l'option --conf spark.sql.shuffle.partitions pour ajouter d'autres partitions aléatoire lorsque vous exécutez spark-submit. Exemple :

spark-submit --conf spark.sql.shuffle.partitions=500 ...

Réduction du nombre de cœurs de l'exécuteur

Cette méthode permet de réduire le nombre maximum de tâches que l'exécuteur traite simultanément, réduisant ainsi la quantité de mémoire utilisée par le conteneur.

Sur un cluster en cours d'exécution :

Modifiez spark-defaults.conf sur le nœud principal. Exemple :

sudo vim /etc/spark/conf/spark-defaults.conf
spark.executor.cores  1

Pour une seule tâche :

Utilisez l'option --executor-cores pour réduire le nombre de cœurs de l'exécuteur lorsque vous exécutez spark-submit. Exemple :

spark-submit --executor-cores 1 ...