AWS re:Postを使用することにより、以下に同意したことになります AWS re:Post 利用規約

Amazon EMR の Spark で「java.lang.ClassNotFoundException」エラーを解決する方法を教えてください。

所要時間2分
0

Amazon EMR の Apache Spark で「java.lang.ClassNotFoundException」エラーを解決したいです。

簡単な説明

Spark の java.lang.ClassNotFoundException エラーは、次の理由で発生します。

  • spark-submit ジョブが、クラスパス内の関連ファイルを見つけることができなかった。
  • ブートストラップアクションまたはカスタム構成により、クラスパスがオーバーライドされている。その結果、クラスローダーは、設定で指定した場所にある JAR ファイルのみを取得します。

解決策

java.lang.ClassNotFoundException エラーを解決するには、スタックトレースをチェックして、欠落しているクラスの名前を特定します。次に、欠落しているクラスを含むカスタム JAR のパスを Spark クラスパスに追加します。カスタム JAR のパスは、実行中のクラスター、新しいクラスター、またはジョブの送信時に追加できます。

実行中のクラスターにカスタム JAR パスを追加する

/etc/spark/conf/spark-defaults.conf で、エラースタックトレースで指定されているクラス名にカスタム JAR のパスを追加します。

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

注: example-custom-jar-path は、実際のカスタム JAR のパスに置き換えてください。

新しいクラスターにカスタム JAR パスを追加する

カスタム JAR パスを /etc/spark/conf/spark-defaults.conf 内の既存のクラスパスに追加するには、新しいクラスターを作成するときに設定オブジェクトを指定します。Amazon EMR バージョン 5.14.0 以降を使用して新しいクラスターを作成してください。

Amazon EMR 5.14.0 から Amazon EMR 5.17.0 の場合は、次の内容を含めてください。

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

Amazon EMR 5.17.0 から Amazon EMR 5.18.0 の場合は、追加の JAR パスとして /usr/share/aws/emr/s3select/lib/emr-s3-select-spark-connector.jar を含めてください。

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

Amazon EMR 5.19.0 から Amazon EMR 5.32.0 の場合は、JAR パスを次のように更新してください。

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

Amazon EMR 5.33.0 から Amazon EMR 5.36.0 の場合は、JAR パスを次のように更新してください。

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

Amazon EMR バージョン 6.0.0 以降では、conf ファイルに複数の JAR パスが含まれているため、この設定を使用して JAR パスを更新することはできません。また、更新する各プロパティ構成の長さには、1024 文字の制限があります。カスタム JAR の場所を spark-defaults.conf に渡すために、ブートストラップアクションを追加します。詳細については、「ブートストラップフェーズ後にすべての Amazon EMR ノートを更新する方法を教えてください」を参照してください。

ブートストラップアクションを追加するには、「カスタムブートストラップアクションを追加する」を参照のうえ、次のアクションを実行します。

  • s3://example-bucket/Bootstraps/script_b.sh は、お使いの Amazon Simple Storage Service (Amazon S3) パスに置き換えてください。
  • /home/hadoop/extrajars/* は、実際のカスタム JAR ファイルパスに置き換えてください。
  • Amazon EMR ランタイムのロールに、Amazon S3 バケットへのアクセスに必要なアクセス許可があることを確認します。
    注: ブートストラップスクリプトを追加すると、スクリプトは特定のジョブではなく、クラスターの Spark 構成に適用されます。

/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 &

注: example-bucket は、お使いの Amazon S3 バケットに置き換えてください。

ジョブの送信時にカスタム JAR パスを追加する

ジョブの送信時にカスタム JAR パスを追加するには、spark-submit コマンドに jars オプションを付けて実行します。詳細については、Apache Spark のウェブサイトで「spark-submit によるアプリケーションの起動」を参照してください。

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

注: example-custom-jar-path は、実際のカスタム JAR のパスに置き換えてください。クラスの競合を防ぐため、jars オプションを使用する場合は、標準の JAR を含めないでください。たとえば、spark-core.jar はクラスターにすでに存在するため、含めないようにします。詳細については、「Spark の設定」を参照してください。

関連情報

Spark の構成 (Apache Spark のウェブサイト)

Amazon EMR の Spark で「メモリ制限を超えたために YARN によってコンテナが強制終了されました」というエラーを解決する方法を教えてください

AWS公式
AWS公式更新しました 2ヶ月前
コメントはありません