Passer au contenu

Comment puis-je corriger l’erreur « Container killed on request. Exit code is 137 » provenant d'une tâche Spark dans Amazon EMR ?

Lecture de 5 minute(s)
0

Ma tâche Apache Spark dans Amazon EMR échoue et je reçois le message d’erreur « Container killed on request. Exit code is 137 ».

Brève description

Lorsqu'un conteneur est à court de mémoire, YARN arrête automatiquement le conteneur et le message d'erreur suivant peut s’afficher :

« Container killed on request" stage failure: 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-###-###-##-###.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-###-###-##-###.compute.internal. Exit status: 137. Diagnostics: Container killed on request. Exit code is 137 »

Résolution

Augmenter la mémoire du pilote ou du conteneur

Pour augmenter la mémoire du conteneur de votre cluster en cours d'exécution ou de votre tâche unique, connectez d'abord le nœud primaire de votre cluster. Puis, modifiez les paramètres spark.executor.memory ou spark.driver.memory dans votre fichier de configuration Spark spark-defaults.conf.

Exécution du cluster

Pour ouvrir spark-defaults.conf, exécutez la commande suivante :

sudo vim /etc/spark/conf/spark-defaults.conf

Pour augmenter la mémoire du conteneur, ajoutez ou modifiez le paramètre spark.executor.memory ou spark.driver.memory dans spark-defaults.conf :

spark.executor.memory 10g
spark.driver.memory 10g

Remarque : remplacez 10g par une valeur adaptée aux ressources disponibles et aux exigences de charge de travail de votre cluster.

Tâche unique

Pour augmenter la mémoire, utilisez l'option --executor-memory ou --driver-memory lorsque vous exécutez la commande spark-submit suivante :

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

Remarque : remplacez 10g par une valeur adaptée aux ressources disponibles et aux exigences de charge de travail de votre cluster.

Vous pouvez également définir MaximizeResourceAllocation sur true dans votre classification de configuration Spark.

Ajouter des partitions Spark

Si vous ne pouvez pas augmenter la mémoire du conteneur, augmentez le nombre de partitions Spark pour réduire la quantité de données traitées et la quantité de mémoire utilisée.

Pour ajouter d'autres partitions Spark, connectez d'abord le nœud primaire de votre cluster, puis exécutez les commandes suivantes dans le shell Spark :

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

Remarque : remplacez 500 par le nombre de partitions qui convient à la taille de vos données.

Augmenter le nombre de partitions aléatoires

Si le problème survient lors d'une transformation importante, telle qu'une jointure ou GroupBy, connectez-vous au nœud primaire de votre cluster et ajoutez d'autres partitions aléatoires. La valeur par défaut est de 200.

Exécution du cluster

Pour ouvrir spark-defaults.conf, exécutez la commande suivante :

sudo vim /etc/spark/conf/spark-defaults.conf

Pour ajouter des partitions aléatoires à votre fichier de configuration, exécutez la commande suivante :

spark.sql.shuffle.partitions 500

Remarque : remplacez 500 par le nombre de partitions qui convient à la taille de vos données.

Tâche unique

Pour ajouter des partitions aléatoires, utilisez l’option --conf spark.sql.shuffle.partitions lorsque vous exécutez spark-submit :

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

Remarque : remplacez 500 par le nombre de partitions qui convient à la taille de vos données.

Réduire le nombre de cœurs d’exécuteur

Lorsque vous réduisez le nombre de cœurs d'exécuteur, vous réduisez également le nombre maximum de tâches que l'exécuteur traite simultanément. Cela permet de réduire la quantité de mémoire utilisée par le conteneur. Pour réduire le nombre de cœurs d'exécuteur, connectez-vous d'abord au nœud primaire de votre cluster, puis modifiez le paramètre de vos cœurs d'exécuteur.

Exécution du cluster

Ouvrez le fichier spark-defaults.conf sur le nœud primaire :

sudo vim /etc/spark/conf/spark-defaults.conf

Pour réduire le nombre de cœurs d'exécuteur, modifiez le paramètre spark.executor.cores :

spark.executor.cores  1

Remarque : remplacez 1 par le nombre minimal de cœurs d'exécuteur dont vous avez besoin.

Tâche unique

Pour réduire le nombre de cœurs d’exécuteur, utilisez l’option --executor-cores lorsque vous exécutez spark-submit :

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

Augmenter la taille de l’instance

Lorsque le système d'exploitation (OS) est à court de mémoire, le système d'exploitation oom_reaper peut également arrêter les conteneurs YARN. Si oom_reaper est à l'origine de l'erreur, utilisez une instance Amazon Elastic Compute Cloud (Amazon EC2) plus grande avec plus de RAM. Pour vous assurer que les conteneurs YARN n'utilisent pas toute la RAM, diminuez yarn.nodemanager.resource.memory-mb.

Pour déterminer si oom_reaper a engendré l’erreur, consultez les journaux de votre instance Amazon EMR pour la sortie de la commande dmesg. Tout d'abord, utilisez l'interface utilisateur ou les journaux du Gestionnaire de ressources YARN pour trouver le nœud primaire ou de tâche sur lequel s'est exécuté le conteneur YARN arrêté. Vérifiez ensuite les journaux d'état de l'instance Amazon EMR sur le nœud avant et après l'arrêt du conteneur.

Dans l'exemple suivant, le noyau arrête le processus qui a l'ID 36787 et correspond au conteneur YARN container_165487060318_0001_01_000244 :

# hows the kernel lookingdmesg | 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

Vérifier l'utilisation du disque et la dégradation du nœud

Si les options de dépannage précédentes ne permettent pas de résoudre le problème, utilisez l'indicateur df-h dans les journaux d'état de l'instance pour vérifier l'utilisation du disque et la dégradation des nœuds. Vérifiez également l'état du nœud sur le tableau de bord AWS Health.

Informations connexes

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

Comment résoudre les échecs d’étape dans les tâches Spark sur Amazon EMR ?

AWS OFFICIELA mis à jour il y a 10 mois