Résoudre les erreurs de mémoire insuffisante de la VM

Cette page fournit des informations sur les erreurs de mémoire insuffisante (OOM, Out Of Memory) de Managed Service pour Apache Spark sur une VM Compute Engine, et explique les étapes à suivre pour résoudre ces erreurs.

Effets des erreurs OOM

Lorsque les VM Managed Service pour Apache Spark rencontrent des erreurs de mémoire insuffisante, les effets incluent les conditions suivantes :

  • Les VM maîtres et de nœud de calcul se figent pendant un certain temps.

  • Les erreurs OOM des VM maîtres entraînent l'échec des jobs avec des erreurs "task not acquired" (tâche non acquise).

  • Les erreurs OOM des VM de nœud de calcul entraînent la perte du nœud sur YARN HDFS, ce qui retarde l'exécution du job Managed Service pour Apache Spark.

Contrôles de la mémoire YARN

Apache YARN fournit les types de contrôles de mémoire suivants :

  • Basé sur l'interrogation (ancien)
  • Strict
  • Elastic

Par défaut, Managed Service pour Apache Spark ne définit pas yarn.nodemanager.resource.memory.enabled pour activer les contrôles de mémoire YARN, pour les raisons suivantes :

  • Le contrôle strict de la mémoire peut entraîner l'arrêt des conteneurs lorsqu'il y a suffisamment de mémoire si les tailles des conteneurs ne sont pas configurées correctement.
  • Les exigences de contrôle élastique de la mémoire peuvent avoir un impact négatif sur l'exécution des jobs.
  • Les contrôles de mémoire YARN peuvent ne pas empêcher les erreurs OOM lorsque les processus consomment de la mémoire de manière agressive.

Protection de la mémoire Managed Service pour Apache Spark

Lorsqu'une VM de cluster Managed Service pour Apache Spark est sous pression de mémoire, la protection de la mémoire Managed Service pour Apache Spark arrête les processus ou les conteneurs jusqu'à ce que la condition OOM soit supprimée.

Managed Service pour Apache Spark fournit une protection de la mémoire pour les nœuds de cluster suivants dans les versions d'image Managed Service pour Apache Spark suivantes :

Rôle 1,5 2.0 2.1 2.2
VM maître 1.5.74+ 2.0.48+ tous tous
VM de nœud de calcul Non disponible 2.0.76+ 2.1.24+ tous
VM du pool de pilotes Non disponible 2.0.76+ 2.1.24+ tous

Identifier et confirmer les arrêts de la protection de la mémoire

Vous pouvez utiliser les informations suivantes pour identifier et confirmer les arrêts de jobs dus à une pression de mémoire.

Arrêts de processus

  • Les processus que la protection de la mémoire Managed Service pour Apache Spark arrête se terminent avec le code 137 ou 143.

  • Lorsque Managed Service pour Apache Spark arrête un processus en raison d'une pression de mémoire, les actions ou conditions suivantes peuvent se produire :

    • Managed Service pour Apache Spark incrémente la métrique cumulative dataproc.googleapis.com/node/problem_count et définit la reason sur ProcessKilledDueToMemoryPressure. Consultez la section Collecte de métriques de ressources Managed Service pour Apache Spark.
    • Managed Service pour Apache Spark écrit un journal google.dataproc.oom-killer avec le message: "A process is killed due to memory pressure: process name. Pour afficher ces messages, activez Logging, puis utilisez le filtre de journal suivant :
      resource.type="cloud_dataproc_cluster"
      resource.labels.cluster_name="CLUSTER_NAME"
      resource.labels.cluster_uuid="CLUSTER_UUID"
      jsonPayload.message:"A process is killed due to memory pressure:"
      

Arrêts de jobs de nœud maître ou de pool de nœuds de pilote

  • Lorsqu'un job de nœud maître ou de pool de nœuds de pilote Managed Service pour Apache Spark s'arrête en raison d'une pression de mémoire, le job échoue avec le code d'erreur Driver received SIGTERM/SIGKILL signal and exited with INT. Pour afficher ces messages, activez Logging, puis utilisez le filtre de journal suivant :

    resource.type="cloud_dataproc_cluster"
    resource.labels.cluster_name="CLUSTER_NAME"
    resource.labels.cluster_uuid="CLUSTER_UUID"
    jsonPayload.message:"Driver received SIGTERM/SIGKILL signal and exited with"
        

    • Consultez le google.dataproc.oom-killer journal ou le dataproc.googleapis.com/node/problem_count pour vérifier que la protection de la mémoire Managed Service pour Apache Spark a arrêté le job (voir Arrêts de processus).

    Solutions :

    • Si le cluster comporte un pool de pilotes, augmentez driver-required-memory-mb pour l'utilisation réelle de la mémoire du job.
    • Si le cluster ne comporte pas de pool de pilotes, recréez-le en réduisant le nombre maximal de jobs simultanés exécutés sur le cluster.
    • Utilisez un type de machine de nœud maître avec une mémoire accrue.

Arrêts de conteneurs YARN de nœud de calcul

  • Managed Service pour Apache Spark écrit le message suivant dans le gestionnaire de ressources YARN : container id exited with code EXIT_CODE. Pour afficher ces messages, activez Logging, puis utilisez le filtre de journal suivant :

    resource.type="cloud_dataproc_cluster"
    resource.labels.cluster_name="CLUSTER_NAME"
    resource.labels.cluster_uuid="CLUSTER_UUID"
    jsonPayload.message:"container" AND "exited with code" AND "which potentially signifies memory pressure on NODE
    
  • Si un conteneur s'est arrêté avec code INT, consultez le google.dataproc.oom-killer journal ou le dataproc.googleapis.com/node/problem_count pour vérifier que la protection de la mémoire Managed Service pour Apache Spark a arrêté le job (voir Arrêts de processus).

    Solutions :

    • Vérifiez que les tailles des conteneurs sont correctement configurées.
    • Envisagez de réduire yarn.nodemanager.resource.memory-mb. Cette propriété contrôle la quantité de mémoire utilisée pour la planification des conteneurs YARN.
    • Si les conteneurs de jobs échouent systématiquement, vérifiez si l'asymétrie des données entraîne une utilisation accrue de conteneurs spécifiques. Si c'est le cas, repartitionnez le job ou augmentez la taille du nœud de calcul pour répondre aux besoins de mémoire supplémentaires.

Ajuster la protection de la mémoire Linux sur le nœud maître (avancé)

Les nœuds maîtres Managed Service pour Apache Spark utilisent l'utilitaire earlyoom pour éviter les blocages du système en libérant de la mémoire lorsque la mémoire disponible est très faible. La configuration par défaut convient à de nombreuses charges de travail. Toutefois, vous devrez peut-être ajuster la configuration si votre nœud maître dispose d'une grande quantité de mémoire et connaît une consommation rapide de mémoire.

Dans les scénarios de forte pression de mémoire, le système peut passer à un état de "thrashing", où il consacre la majeure partie de son temps à la gestion de la mémoire et ne répond plus. Cela peut se produire si rapidement que earlyoom ne parvient pas à agir en fonction de ses paramètres par défaut ou n'agit pas avant l'appel de la réponse OOM du noyau.

Avant de commencer

  • Il s'agit d'une option de réglage avancée. Avant d'ajuster les paramètres earlyoom, privilégiez d'autres solutions, telles que l'utilisation d'une VM maître avec plus de mémoire, la réduction de la simultanéité des jobs ou l'optimisation de l'utilisation de la mémoire des jobs.

Personnaliser les paramètres earlyoom

La configuration earlyoom par défaut utilise une quantité fixe de mémoire libre comme déclencheur. Sur les machines virtuelles disposant d'une grande quantité de RAM, par exemple 32GB ou plus, cette quantité fixe peut représenter une petite fraction de la mémoire totale. Le système est donc susceptible de connaître des pics soudains d'utilisation de la mémoire.

Pour personnaliser les paramètres earlyoom, connectez-vous au nœud maître et modifiez le fichier de configuration.

  1. Connectez-vous à votre nœud maître à l'aide de SSH.

  2. Ouvrez le fichier de configuration pour le modifier :

    sudo nano /etc/default/earlyoom
    
  3. Ajustez le seuil de mémoire minimal. Recherchez la ligne EARLYOOM_ARGS. L'option -M <kbytes> définit la quantité minimale de mémoire libre en Kio que earlyoom tente de maintenir. La valeur par défaut est -M 65536, soit 64 MiB.

    Pour un nœud maître disposant d'une mémoire importante, augmentez cette valeur. Par exemple, pour définir le seuil sur 1 GiB (1048576 KiB), modifiez la ligne comme suit :

    EARLYOOM_ARGS="-r 15 -M 1048576 -s 1"
    

    Remarques :

    • -r : intervalle du rapport de mémoire en secondes
    • -s : seuil d'espace d'échange pour déclencher earlyoom
  4. Redémarrez le service earlyoom pour appliquer les modifications :

    sudo systemctl restart earlyoom