Ir para o conteúdo

Como resolvo o erro “java.lang.ClassNotFoundException” error in Spark on Amazon EMR?

4 minuto de leitura
0

Quero resolver o erro “java.lang.ClassNotFoundException” error in Apache Spark on Amazon EMR.

Breve descrição

O erro java.lang.ClassNotFoundException no Spark ocorre pelos seguintes motivos:

  • O trabalho spark-submit não consegue encontrar os arquivos relevantes no caminho da classe.
  • Uma ação de bootstrap ou configuração personalizada está substituindo os caminhos da classe. Como resultado, o carregador de classes coleta somente os arquivos JAR que existem no local que você especificou na sua configuração.

Resolução

Para resolver o erro java.lang.ClassNotFoundException, verifique o rastreamento de pilha para encontrar o nome da classe ausente. Em seguida, adicione o caminho do seu JAR personalizado que contém a classe ausente ao caminho da classe Spark. É possível adicionar o caminho do seu JAR personalizado em um cluster em execução, em um novo cluster ou ao enviar um trabalho.

Adicione seu caminho JAR personalizado em um cluster em execução

Em /etc/spark/conf/spark-defaults.conf, adicione o caminho do seu JAR personalizado aos nomes das classes especificados no rastreamento da pilha de erros.

Exemplo:

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

Observação: substitua example-custom-jar-path pelo seu caminho JAR personalizado.

Adicione seu caminho JAR personalizado em um novo cluster

Para adicionar seu caminho JAR personalizado aos caminhos de classe existentes em /etc/spark/conf/spark-defaults.conf, forneça um objeto de configuração ao criar um cluster novo. Use as versões 5.14.0 ou posteriores do Amazon EMR para criar um novo cluster.

Para o Amazon EMR 5.14.0 ao Amazon EMR 5.17.0, inclua o seguinte:

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

Para o Amazon EMR 5.17.0 ao Amazon EMR 5.18.0, inclua /usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar como o caminho JAR adicional:

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

Para o Amazon EMR 5.19.0 ao Amazon EMR 5.32.0, atualize o caminho do JAR, da seguinte forma:

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

Para o Amazon EMR 5.33.0 ao Amazon EMR 5.36.0, atualize o caminho do JAR, da seguinte forma:

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

Para as versões 6.0.0 e posteriores do Amazon EMR, não é possível usar a configuração para atualizar o caminho JAR porque o arquivo conf inclui vários caminhos JAR. Além disso, o tamanho de cada configuração de propriedade que você atualiza não pode exceder 1.024 caracteres. Para passar a localização personalizada do JAR para spark-defaults.conf, adicione uma ação de bootstrap. Para mais informações, consulte Como faço para atualizar todos os nós do Amazon EMR após a fase de bootstrap?

Para adicionar uma ação de bootstrap, consulte Adicionar ações de bootstrap personalizadas e, em seguida, execute as seguintes ações:

  • Substitua s3://example-bucket/Bootstraps/script_b.sh pelo caminho do Amazon Simple Storage Service (Amazon S3).
  • Substitua /home/hadoop/extrajars/* pelo caminho do arquivo JAR personalizado.
  • Confirme se o perfil runtime do Amazon EMR tem as permissões necessárias para acessar o bucket do Amazon S3.
    Observação: quando você adiciona o script de bootstrap, o script se aplica à configuração do Spark do cluster em vez de a um trabalho específico.

Exemplo de script para alterar /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 &

Observação: substitua example-bucket pelo seu bucket do Amazon S3.

Adicione seu caminho JAR personalizado ao enviar um trabalho

Para adicionar seu caminho JAR personalizado ao enviar um trabalho, execute o comando spark-submit com a opção jars. Para obter mais informações, consulte Lançamento de aplicações com spark-submit no site do Apache Spark.

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

Observação: substitua example-custom-jar-path pelo seu caminho JAR personalizado. Para evitar conflitos de classe, não inclua JARs padrão ao usar a opção jars. Por exemplo, não inclua spark-core.jar porque ele já existe no cluster. Para mais informações, consulte Configurar o Spark.

Informações relacionadas

Configuração do Spark no site do Apache Spark

How do I resolve the error "Container killed by YARN for exceeding memory limits" in Spark on Amazon EMR? (Como resolvo o erro “Contêiner eliminado pelo YARN por exceder os limites de memória” do Spark no Amazon EMR?)

AWS OFICIALAtualizada há um ano