Direkt zum Inhalt

Wie behebe ich den Fehler „Container killed by YARN for exceeding memory limits“ in Spark auf Amazon EMR?

Lesedauer: 5 Minute
0

Ich möchte den Fehler „Container killed by YARN for exceeding memory limits“ in Spark auf Amazon EMR beheben.

Lösung

Die Grundursache und die geeignete Lösung für diesen Fehler hängen von deiner Workload ab. Verwende die folgenden Methoden zur Problembehandlung in der folgenden Reihenfolge, um den Fehler zu beheben.

Speicher-Overhead erhöhen

Der Speicher-Overhead ist die Menge an Off-Heap-Speicher, die jedem Executor zugewiesen wird. Standardmäßig setzt Spark den Speicher-Overhead entweder auf 10 % des Executor-Speichers oder auf 384, je nachdem, welcher Wert höher ist. Direkte Java-NIO-Puffer, Thread-Stacks, gemeinsam genutzte native Bibliotheken und Speicher-zugeordnete Dateien nutzen diesen Speicher-Overhead.

Erhöhe den Speicher-Overhead schrittweise auf bis zu 25 %. Die Summe aus Treiber- oder Executor-Speicher plus Speicher-Overhead muss kleiner sein als yarn.nodemanager.resource.memory-mb for your instance type:

„spark.driver/executor.memory + spark.driver/executor.memoryOverhead < yarn.nodemanager.resource.memory-mb“

Wenn der Fehler im Treiber-Container oder Executor-Container auftritt, erhöhe den Speicher-Overhead nur für den Container, in dem der Fehler aufgetreten ist. Du kannst den Speicher-Overhead in einem laufenden Cluster, einem neuen Cluster oder beim Senden eines Auftrags erhöhen.

Laufender Cluster

Ändere spark-defaults.conf auf dem Primärknoten.

Zum Beispiel:

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

Neuer Cluster

Füge beim Starten des Clusters ein Konfigurationsobjekt hinzu, das dem folgenden Beispiel ähnelt:

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

Einzelner Auftrag

Verwende die Option --conf, um den Speicher-Overhead zu erhöhen, wenn du spark-submit ausführst.

Beispiel:

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

Wenn du den Fehler weiterhin erhältst, nachdem du den Speicher-Overhead erhöht hast, reduziere die Anzahl der Executor-Cores.

Reduzieren der Anzahl der Executor-Cores

Hinweis: Mache alle Änderungen rückgängig, die du im vorherigen Abschnitt an spark-defaults.conf vorgenommen hast.

Wenn du die Anzahl der Executor-Cores reduzierst, reduziere die maximale Anzahl von Aufgaben, die der Executor ausführen kann, wodurch der benötigte Arbeitsspeicher reduziert wird. Verringere die Anzahl der Cores für den Treiber oder den Executor, je nachdem, welcher Treiber-Container den Fehler auslöst oder welcher andere Executor-Container den Fehler erhält.

Laufender Cluster

Ändere spark-defaults.conf auf dem Primärknoten.

Beispiel:

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

Neuer Cluster

Füge beim Starten des Clusters ein Konfigurationsobjekt hinzu, das dem folgenden Beispiel ähnelt:

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

Einzelner Auftrag

Verwende die Option --executor-cores, um die Anzahl der Executor-Cores zu reduzieren, wenn du spark-submit ausführst.

Beispiel:

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

Wenn du die Fehlermeldung weiterhin erhältst, erhöhe die Anzahl der Partitionen.

Die Anzahl der Partitionen erhöhen

Hinweis: Mache alle Änderungen rückgängig, die du im vorherigen Abschnitt an spark-defaults.conf vorgenommen hast.

Um die Anzahl der Partitionen zu erhöhen, erhöhe den Wert von spark.default.parallelism für rohe, resiliente verteilte Datensätze oder führe einen .repartition()-Vorgang aus.

Wenn du die Anzahl der Partitionen erhöhst, reduziere den Speicherbedarf pro Partition. Spark verwendet Cluster-RAM in hohem Maße als effektive Methode zur Maximierung der Geschwindigkeit. Daher musst du die Speichernutzung mit Ganglia (für Amazon EMR Version 6.15) oder Amazon-CloudWatch-Agent (für Amazon EMR 7.0 und höher) überwachen. Stelle anschließend sicher, dass die Cluster-Einstellungen und die Partitionierungsstrategie deinen wachsenden Datenanforderungen entsprechen. Wenn du weiterhin die Fehlermeldung „Container killed by YARN for exceeding memory limits“ erhältst, erhöhe den Treiber- und Executor-Speicher.

Den Treiber- und Executor-Speicher erhöhen

Hinweis: Mache alle Änderungen rückgängig, die du im vorherigen Abschnitt an spark-defaults.conf vorgenommen hast.

Wenn der Fehler entweder in einem Treiber-Container oder einem Executor-Container auftritt, erhöhe den Speicher entweder für den Treiber oder den Executor, aber nicht für beide. Stelle sicher, dass die Summe aus Treiber- oder Executor-Speicher plus Treiber- oder Executor-Speicher-Overhead immer kleiner ist als der Wert von yarn.nodemanager.resource.memory-mb for your EC2 instance type:

„spark.driver/executor.memory + spark.driver/executor.memoryOverhead < yarn.nodemanager.resource.memory-mb“

Laufender Cluster

Ändere spark-defaults.conf auf dem Primärknoten.

Beispiel:

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

Neuer Cluster

Füge ein Konfigurationsobjekt hinzu, das dem folgenden ähnelt, wenn du einen Cluster startest:


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

Einzelner Auftrag

Verwende die Optionen --executor-memory und --driver-memory, um den Arbeitsspeicher zu erhöhen, wenn du spark-submit ausführst.

Beispiel:

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

Weitere Schritte zur Problembehandlung:

Solltest du die Fehlermeldung weiterhin erhalten, gehe wie folgt vor:

  • Führe deine Anwendung anhand eines Beispieldatensatzes aus. Benchmarking ist eine bewährte Methode und kann dir helfen, Verlangsamungen und schiefe Partitionen zu erkennen, die zu Speicherproblemen führen.
  • Verarbeite die Mindestmenge an erforderlichen Daten. Wenn du die Daten nicht oder erst spät in der Anwendungsausführung filterst, können überschüssige Daten die Anwendung verlangsamen. Dies kann die Wahrscheinlichkeit eines Speicherausfalls erhöhen.
  • Partitioniere die Daten, um nur die erforderlichen Daten zu erfassen.
  • Verwende eine andere Partitionierungsstrategie. Führe die Partitionierung beispielsweise mit einem alternativen Schlüssel durch, um große Partitionen und schiefe Partitionen zu vermeiden.
  • Die EC2-Instance verfügt möglicherweise nicht über die Speicherressourcen, die für die Workload erforderlich sind. Wechsle zu einem größeren speicheroptimierten Instance-Typ. Wenn du nach dem Ändern des Instance-Typs weiterhin Speicherausnahmen erhältst, probiere die Methoden zur Problembehandlung auf der neuen Instance aus.

Ähnliche Informationen

Spark configuration (Spark-Konfiguration) auf der Apache Spark-Website

Wie behebe ich den Fehler „java.lang.ClassNotFoundException“ in Spark auf Amazon EMR?

AWS OFFICIALAktualisiert vor 6 Monaten