Comment corriger les erreurs « Container killed on request. Exit code is 137 » dans Spark sur Amazon EMR ?

Lecture de 4 minute(s)
0

Ma tâche Apache Spark sur Amazon EMR échoue en raison de l’erreur de phase « 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 (exécuteur Spark) manque de mémoire, YARN le désactive automatiquement. Cela entraîne l’erreur « Container killed on request. Exit code is 137. » Ces erreurs peuvent survenir à différentes étapes de la tâche, qu’il s’agisse de transformations étroites ou étendues. Les conteneurs YARN peuvent également être désactivés par le désactivateur oom_reaper du système d’exploitation lorsque celui-ci manque de mémoire, ce qui entraîne l’erreur « Container killed on request. Exit code is 137. »

Résolution

Utilisez une ou plusieurs des méthodes suivantes pour corriger les échecs de phase « Exit status: 137. »

Augmentation de la mémoire du pilote ou de l’exécuteur

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

Sur un cluster en cours d’exécution :

Modifiez le paramètre 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 tâche unique :

Utilisez l’option --executor-memory ou --driver-memory afin d’augmenter la mémoire lorsque vous exécutez spark-submit. Exemple :

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

Ajout de 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. Cela permet de réduire la quantité de données traitées par une seule tâche Spark et ainsi de réduire la mémoire globale utilisée par un seul exécuteur. Utilisez le code Scala suivant pour ajouter des partitions Spark :

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

Augmentation du nombre de partitions aléatoires

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

Sur un cluster en cours d’exécution :

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

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

Pour une tâche unique :

Utilisez l’option --conf spark.sql.shuffle.partitions pour ajouter des partitions aléatoires lorsque vous exécutez spark-submit. Exemple :

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

Réduction du nombre de cœurs d’exécuteur

Réduire le nombre de cœurs d’exécuteur permet de diminuer le nombre maximum de tâches que l’exécuteur traite simultanément. Cela réduit la quantité de mémoire utilisée par le conteneur.

Sur un cluster en cours d’exécution :

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

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

Pour une tâche unique :

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

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

Augmentation de la taille de l’instance

Les conteneurs YARN peuvent également être désactivés par le désactivateur oom_reaper du système d’exploitation lorsque celui-ci manque de mémoire. Si cette erreur est due à oom_reaper, utilisez une instance plus grande avec davantage de RAM. Vous pouvez également réduire la taille de yarn.nodemanager.resource.memory-mb pour empêcher les conteneurs YARN d’utiliser toute la RAM d’Amazon EC2.

Vous pouvez déterminer si l’erreur est due à oom_reaper en consultant les journaux de votre instance Amazon EMR pour la sortie de commande dmesg. Commencez par trouver le nœud principal ou de tâche sur lequel s’exécutait le conteneur YARN désactivé. Vous pouvez trouver ces informations à l’aide de l’interface utilisateur ou des journaux de YARN Resource Manager. Consultez ensuite les journaux d’état de l’instance Amazon EMR sur ce nœud avant et après la désactivation du conteneur pour découvrir ce qui a désactivé le processus.

Dans l’exemple suivant, le processus n° 36787 correspondant au conteneur YARN container_165487060318_0001_01_000244 a été désactivé par le noyau (désactivateur OOM de Linux) :

# hows the kernel looking
dmesg | tail -n 25

[ 3910.032284] Out of memory: Kill process 36787 (java) score 96 or sacrifice child
[ 3910.043627] Killed process 36787 (java) total-vm:15864568kB, anon-rss:13876204kB, file-rss:0kB, shmem-rss:0kB
[ 3910.748373] oom_reaper: reaped process 36787 (java), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

Informations connexes

Comment corriger l’erreur « Container killed by YARN for exceeding memory limits » dans Spark sur Amazon EMR ?

Comment corriger les erreurs de phase dans les tâches Spark sur Amazon EMR ?

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 2 ans