Passer au contenu

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

Lecture de 6 minute(s)
0

Je souhaite résoudre l’erreur « Container killed by YARN for exceeding memory limits » dans Spark sur Amazon EMR.

Résolution

La cause première et la solution appropriée à cette erreur dépendent de votre charge de travail. Pour résoudre l'erreur, utilisez les méthodes de résolution de problèmes suivantes, dans l'ordre suivant.

Augmenter la charge de mémoire

La charge de mémoire est la quantité de mémoire hors tas allouée à chaque exécuteur. Par défaut, Spark définit la charge de mémoire à 10 % de la mémoire de l'exécuteur ou à 384, la valeur la plus élevée étant retenue. Les tampons directs Java NIO, les piles de threads, les bibliothèques natives partagées ou les fichiers mappés en mémoire utilisent cette charge de mémoire.

Augmentez progressivement la charge de mémoire, jusqu'à 25 %. La somme de la mémoire du pilote ou de l'exécuteur et de la charge de mémoire doit être inférieure à yarn.nodemanager.resource.memory-mb pour votre type d’instance :

« spark.driver/executor.memory + spark.driver/Executor.MemoryOverhead < yarn.nodemanager.resource.memory-mb »

Si l'erreur se produit dans le conteneur du pilote ou dans le conteneur de l'exécuteur, augmentez la charge de mémoire pour le conteneur où l’erreur s’est produite. Vous pouvez augmenter la charge de mémoire sur un cluster en cours, sur un nouveau cluster ou lorsque vous soumettez une tâche.

Cluster en cours

Modifiez spark-defaults.conf sur le nœud primaire.

Exemple :

sudo vim /etc/spark/conf/spark-defaults.conf
spark.driver.memoryOverhead 512
spark.executor.memoryOverhead 512

Nouveau cluster

Ajoutez un objet de configuration similaire à l'exemple suivant lorsque vous lancez le cluster :

[
  {
    "Classification": "spark-defaults",
    "Properties": {
      "spark.driver.memoryOverhead": "512",
      "spark.executor.memoryOverhead": "512"
    }
  }
]

Tâche unique

Pour augmenter la charge de mémoire lorsque vous exécutez spark-submit, utilisez l'option --conf.

Exemple :

spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --conf spark.driver.memoryOverhead=512 --conf spark.executor.memoryOverhead=512 /usr/lib/spark/examples/jars/spark-examples.jar 100

Si vous continuez de recevoir l'erreur après avoir augmenté la charge de mémoire, réduisez le nombre de cœurs d'exécuteur.

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

Remarque : annulez les modifications que vous avez apportées à spark-defaults.conf dans la section précédente.

Lorsque vous réduisez le nombre de cœurs d'exécuteur, vous réduisez le nombre maximum de tâches que l'exécuteur peut effectuer, ce qui réduit la quantité de mémoire requise. En fonction du conteneur de pilotes qui génère l'erreur ou de l'autre conteneur d'exécuteur qui reçoit l'erreur, diminuez le nombre de cœurs pour le pilote ou l'exécuteur.

Cluster en cours

Modifiez spark-defaults.conf sur le nœud primaire.

Exemple :

sudo vim /etc/spark/conf/spark-defaults.confspark.driver.cores  3
spark.executor.cores  3

Nouveau cluster

Ajoutez un objet de configuration similaire à l'exemple suivant lorsque vous lancez le cluster :

[
  {
    "Classification": "spark-defaults",
    "Properties": {"spark.driver.cores" : "3",
      "spark.executor.cores": "3"
    }
  }
]

Tâche unique

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

Exemple :

spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --executor-cores 3 --driver-cores 3 /usr/lib/spark/examples/jars/spark-examples.jar 100

Si vous continuez de recevoir le message d'erreur, augmentez le nombre de partitions.

Augmenter le nombre de partitions

Remarque : annulez les modifications que vous avez apportées à spark-defaults.conf dans la section précédente.

Pour augmenter le nombre de partitions, augmentez la valeur de spark.default.parallelism pour les jeux de données distribués résilients bruts, ou exécutez une opération .repartition().

Lorsque vous augmentez le nombre de partitions, vous réduisez la quantité de mémoire requise par partition. Spark utilise largement la RAM du cluster comme moyen efficace d'optimiser la vitesse. Par conséquent, vous devez surveiller l'utilisation de la mémoire à l'aide de Ganglia (pour Amazon EMR version 6.15) ou de l'agent Amazon CloudWatch (pour Amazon EMR 7.0 et versions ultérieures). Vérifiez ensuite que les paramètres de votre cluster et votre stratégie de partitionnement répondent à vos besoins croissants en matière de données. Si vous continuez de recevoir le message d'erreur « Container killed by YARN for exceeding memory limits », augmentez la mémoire du pilote et de l'exécuteur.

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

Remarque : annulez les modifications que vous avez apportées à spark-defaults.conf dans la section précédente.

Si l'erreur se produit dans un conteneur de pilote ou dans un conteneur d'exécuteur, augmentez la mémoire pour le pilote ou l'exécuteur, mais pas pour les deux. Assurez-vous que la somme de la mémoire du pilote ou de l'exécuteur et de la charge de mémoire du pilote ou de l'exécuteur est toujours inférieure à la valeur de yarn.nodemanager.resource.memory-mb pour le type d’instance EC2 :

« spark.driver/executor.memory + spark.driver/Executor.MemoryOverhead < yarn.nodemanager.resource.memory-mb »

Cluster en cours

Modifiez spark-defaults.conf sur le nœud primaire.

Exemple :

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

Nouveau cluster

Ajoutez un objet de configuration similaire à l’objet suivant lorsque vous lancez un cluster :


[  
  {
    "Classification": "spark-defaults",
    "Properties": {
      "spark.executor.memory": "1g",
      "spark.driver.memory":"1g",
    }
  }
]

Tâche unique

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

Exemple :

spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --executor-memory 1g --driver-memory 1g /usr/lib/spark/examples/jars/spark-examples.jar 100

Autres étapes de résolution des problèmes

Si vous continuez de recevoir le message d'erreur, effectuez les actions suivantes :

  • Exécutez votre application sur un exemple de jeu de données. L'analyse comparative est une bonne pratique qui peut vous aider à repérer les ralentissements et les partitions asymétriques qui entraînent des problèmes de mémoire.
  • Traitez le minimum de données requises. Si vous ne filtrez pas vos données, ou si vous les filtrez tardivement lors de l'exécution de l'application, un excès de données risque de ralentir l'application. Cela peut augmenter le risque d'une exception de mémoire.
  • Partitionnez vos données pour n'ingérer que les données requises.
  • Utilisez une stratégie de partitionnement différente. Par exemple, partitionnez sur une clé alternative afin d’éviter les partitions volumineuses et les partitions asymétriques.
  • Votre instance EC2 ne dispose peut-être pas des ressources mémoire requises pour votre charge de travail. Passez à un type d'instance plus grand et optimisé pour la mémoire. Si vous continuez de recevoir des exceptions de mémoire après avoir changé de type d'instance, essayez les méthodes de résolution de problèmes sur la nouvelle instance.

Informations connexes

Configuration de Spark sur le site Web d'Apache Spark

Comment puis-je résoudre l'erreur « java.lang.ClassNotFoundException » dans Spark sur Amazon EMR ?

AWS OFFICIELA mis à jour il y a 5 mois