Salta al contenuto

Come posso risolvere l’errore "java.lang.ClassNotFoundException" in Spark su Amazon EMR?

4 minuti di lettura
0

Desidero risolvere l'errore "java.lang.ClassNotFoundException" in Apache Spark su Amazon EMR.

Breve descrizione

L'errore java.lang.ClassNotFoundException in Spark si verifica per i seguenti motivi:

  • Il processo spark-submit non riesce a trovare i file pertinenti nel percorso della classe.
  • Un'azione di bootstrap o una configurazione personalizzata sovrascrive i percorsi delle classi. Di conseguenza, il class loader preleva solo i file JAR presenti nella posizione specificata nella configurazione.

Risoluzione

Per risolvere l'errore java.lang.ClassNotFoundException, controlla la traccia dello stack per individuare il nome della classe mancante. Quindi aggiungi il percorso del JAR personalizzato contenente la classe mancante al percorso della classe Spark. Puoi aggiungere il percorso del JAR personalizzato in un cluster in esecuzione, in un nuovo cluster o quando invii un processo.

Aggiungi il percorso del JAR personalizzato in un cluster in esecuzione

In /etc/spark/conf/spark-defaults.conf, aggiungi il percorso del JAR personalizzato ai nomi delle classi specificati nella traccia dello stack di errori.

Esempio:

sudo vim /etc/spark/conf/spark-defaults.conf
spark.driver.extraClassPath <other existing jar locations>:example-custom-jar-path
spark.executor.extraClassPath <other existing jar locations>:example-custom-jar-path

Nota: sostituisci example-custom-jar-path con il percorso del tuo JAR personalizzato.

Aggiungi il percorso del JAR personalizzato in un nuovo cluster

Per aggiungere il percorso del JAR personalizzato ai percorsi delle classi esistenti in /etc/spark/conf/spark-defaults.conf, fornisci un oggetto di configurazione quando crei un nuovo cluster. Utilizza Amazon EMR versione 5.14.0 o successive per creare un nuovo cluster.

Per Amazon EMR 5.14.0 fino ad Amazon EMR 5.17.0, includi quanto segue:

[  {
    "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/*"
    }
  }
]

Per Amazon EMR 5.17.0 fino ad Amazon EMR 5.18.0, includi /usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar come percorso di un JAR aggiuntivo:

[  {
    "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/*"
    }
  }
]

Per Amazon EMR 5.19.0 fino ad Amazon EMR 5.32.0, aggiorna il percorso del JAR come segue:

[
  {
    "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/*"
    }
  }
]

Per Amazon EMR 5.33.0 fino ad Amazon EMR 5.36.0, aggiorna il percorso del JAR come segue:

[
  {
    "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/"
    }
  }
]

Per le versioni 6.0.0 e successive di Amazon EMR, non puoi utilizzare la configurazione per aggiornare il percorso del JAR perché il file conf include i percorsi di diversi JAR. Inoltre, la lunghezza di ogni configurazione di proprietà che si aggiorna non può superare i 1.024 caratteri. Per passare la posizione del JAR personalizzato a spark-defaults.conf, aggiungi un'azione di bootstrap. Per ulteriori informazioni, consulta Come posso aggiornare tutti i nodi Amazon EMR dopo l'azione di bootstrap?

Per aggiungere un'azione di bootstrap, consulta Aggiunta di operazioni di bootstrap personalizzate, quindi esegui queste azioni:

  • Sostituisci s3://example-bucket/Bootstraps/script_b.sh con il tuo percorso Amazon Simple Storage Service (Amazon S3).
  • Sostituisci /home/hadoop/extrajars/* con il percorso del tuo file JAR personalizzato.
  • Verifica che il ruolo di runtime di Amazon EMR abbia le autorizzazioni necessarie per accedere al bucket Amazon S3.
    **Nota:**Quando aggiungi lo script di bootstrap, lo script si applica alla configurazione Spark del cluster anziché a un processo specifico.

Esempio di script per modificare /etc/spark/conf/spark-defaults.conf:

#!/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
Launch the EMR cluster and add a bootstrap action similar to the following:
#!/bin/bash
pwd
aws s3 cp s3://example-bucket/Bootstraps/script_b.sh .
chmod +x script_b.sh
nohup ./script_b.sh &

Nota: sostituisci example-bucket con il tuo bucket Amazon S3.

Aggiungi il percorso del JAR personalizzato quando invii un processo

Per aggiungere il percorso del JAR personalizzato quando invii un processo, esegui il comando spark-submit con l'opzione jars. Per ulteriori informazioni, consulta Launching Applications with spark-submit (Avvio di applicazioni con spark-submit) sul sito web Apache Spark.

spark-submit --deploy-mode client --class org.apache.spark.examples.SparkPi --master yarn spark-examples.jar 100 --jars example-custom-jar-path

Nota: sostituisci example-custom-jar-path con il percorso del tuo JAR personalizzato. Per evitare conflitti di classe, non includere JAR standard quando utilizzi l'opzione jars. Ad esempio, non includere spark-core.jar perché esiste già nel cluster. Per ulteriori informazioni, consulta Configurazione di Spark.

Informazioni correlate

Spark configuration (Configurazione di Spark) sul sito web Apache Spark

Come posso risolvere l'errore “Container killed by YARN for exceeding memory limits” in Spark su Amazon EMR?

AWS UFFICIALEAggiornata un anno fa