Wie löse ich die „java.lang.ClassNotFoundException“ in Spark auf Amazon EMR?
Wenn ich benutzerdefinierte JAR-Dateien in einem Spark-Submit- oder PySpark-Job auf Amazon EMR verwende, erhalte ich einen java.lang.ClassNotFoundException-Fehler.
Kurzbeschreibung
Dieser Fehler tritt auf, wenn eine der folgenden Bedingungen zutrifft:
- Der Spark-Submit-Job kann die relevanten Dateien im Klassenpfad nicht finden.
- Eine Bootstrap-Aktion oder eine benutzerdefinierte Konfiguration überschreibt die Klassenpfade. In diesem Fall nimmt der Klassenlader nur die JAR-Dateien auf, die an dem Speicherort vorhanden sind, den Sie in Ihrer Konfiguration angegeben haben.
Behebung
Überprüfen Sie den Stack-Trace, um den Namen der fehlenden Klasse zu finden. Fügen Sie dann den Pfad Ihres benutzerdefinierten JARs (das die fehlende Klasse enthält) zum Spark-Klassenpfad hinzu. Sie können dies tun, während der Cluster läuft, wenn Sie einen neuen Cluster starten oder wenn Sie einen Job einreichen.
Auf einem laufenden Cluster
Hängen Sie in /etc/spark/conf/spark-defaults.conf den Pfad Ihrer benutzerdefinierten JAR an die Klassennamen an, die im Error-Stack-Trace angegeben sind. Im folgenden Beispiel ist /home/hadoop/extrajars/* der benutzerdefinierte JAR-Pfad.
sudo vim /etc/spark/conf/spark-defaults.conf spark.driver.extraClassPath <other existing jar locations>:/home/hadoop/extrajars/* spark.executor.extraClassPath <other existing jar locations>:/home/hadoop/extrajars/*
Auf einem neuen Cluster
Hängen Sie den benutzerdefinierten JAR-Pfad an die vorhandenen Klassenpfade in /etc/spark/conf/spark-defaults.conf an, indem Sie beim Erstellen eines Clusters ein Konfigurationsobjekt angeben.
**Hinweis:**Um diese Option verwenden zu können, müssen Sie einen Cluster mit der Amazon EMR-Version 5.14.0 oder höher erstellen.
Fügen Sie für Amazon EMR 5.14.0 bis Amazon EMR 5.17.0 Folgendes hinzu:
[ { "Classification": "spark-defaults", "Properties": { "spark.driver.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/home/hadoop/extrajars/*", "spark.executor.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/home/hadoop/extrajars/*" } } ]
Geben Sie für Amazon EMR 5.17.0 bis Amazon EMR 5.18.0 /usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar als zusätzlichen JAR-Pfad an:
[ { "Classification": "spark-defaults", "Properties": { "spark.driver.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/*", "spark.executor.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/*" } } ]
Für Amazon EMR 5.19.0 bis Amazon EMR 5.32.0 aktualisieren Sie den JAR-Pfad wie folgt:
[ { "Classification": "spark-defaults", "Properties": { "spark.driver.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/*", "spark.executor.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/*" } } ]
Für Amazon EMR 5.33.0 bis Amazon EMR 5.34.0 aktualisieren Sie den JAR-Pfad wie folgt:
[ { "Classification": "spark-defaults", "Properties": { "spark.driver.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/", "spark.executor.extraClassPath": "/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/goodies/lib/emr-spark-goodies.jar:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar:/home/hadoop/extrajars/" } } ]
Für Amazon EMR Release-Version 6.0.0 und höher funktioniert die Aktualisierung des JAR-Pfads mithilfe der Konfiguration nicht. Bei diesen Versionen enthält die .conf-Datei mehrere JAR-Dateipfade. Außerdem darf die Länge der Konfiguration für jede Eigenschaft, die Sie aktualisieren, nicht mehr als 1024 Zeichen betragen. Sie können jedoch eine Bootstrap-Aktion hinzufügen, um den benutzerdefinierten JAR-Speicherort an spark-defaults.conf zu übergeben. Weitere Informationen finden Sie unter Wie aktualisiere ich alle Amazon EMR-Knoten nach der Bootstrap-Phase?
Erstellen Sie ein Bash-Skript, das dem folgenden ähnelt:
Hinweis:
- Achten Sie darauf, s3://doc-example-bucket/Bootstraps/script_b.sh durch den Amazon Simple Storage Service (Amazon S3)-Pfad Ihrer Wahl zu ersetzen.
- Achten Sie darauf, /home/hadoop/extrajars/* durch Ihren benutzerdefinierten JAR-Dateipfad zu ersetzen.
- Stellen Sie sicher, dass die Amazon EMR-Ausführungsrolle über Berechtigungen für den Zugriff auf diesen S3-Bucket verfügt.
#!/bin/bash # # This is an example of script_b.sh for changing /etc/spark/conf/spark-defaults.conf # while [ ! -f /etc/spark/conf/spark-defaults.conf ] do sleep 1 done # # Now the file is available, do your work here # sudo sed -i '/spark.*.extraClassPath/s/$/:\/home\/hadoop\/extrajars\/\*/' /etc/spark/conf/spark-defaults.conf exit 0
Starten Sie den EMR-Cluster und fügen Sie eine Bootstrap-Aktion hinzu, die der folgenden ähnelt:
#!/bin/bash pwd aws s3 cp s3://doc-example-bucket/Bootstraps/script_b.sh . chmod +x script_b.sh nohup ./script_b.sh &
Für einen einzelnen Job
Verwenden Sie die Option --jars, um den benutzerdefinierten JAR-Pfad zu übergeben, wenn Sie spark-submit ausführen.
Beispiel:
spark-submit --deploy-mode client --class org.apache.spark.examples.SparkPi --master yarn spark-examples.jar 100 --jars /home/hadoop/extrajars/*
**Hinweis:**Um Klassenkonflikte zu vermeiden, fügen Sie keine Standard-JARs ein, wenn Sie die Option --jars verwenden. Fügen Sie beispielsweise spark-core.jar nicht ein, da es bereits im Cluster vorhanden ist.
Weitere Informationen zur Konfiguration von Klassifizierungen finden Sie unter Spark konfigurieren.
Verwandte Informationen
Ähnliche Videos
Relevanter Inhalt
- AWS OFFICIALAktualisiert vor 2 Jahren
- AWS OFFICIALAktualisiert vor 2 Jahren
- AWS OFFICIALAktualisiert vor 2 Jahren
- AWS OFFICIALAktualisiert vor 2 Monaten