如何解决 Amazon EMR 上的 Spark 中的“java.lang.ClassNotFoundException”异常?

上次更新时间:2020 年 1 月 8 日

我在 Amazon EMR 上使用 spark-submit 或 PySpark 作业中的自定义 JAR 文件时,收到 java.lang.ClassNotFoundException 错误。

简短描述

在以下中的一项为真时,会发生此错误:

  • spark-submit 作业无法在类路径中找到相关文件。
  • 引导操作或自定义配置覆盖了类路径。发生此情况时,类加载器会仅选择您在配置中指定的位置中存在的 JAR 文件。

解决方法

检查堆栈跟踪以查找缺失类的名称。然后,将您的自定义 JAR 的路径(包含缺失的类)添加到 Spark 类路径中。您可以在集群运行、启动新集群或者提交作业时执行此操作。

在正在运行的集群上:

/etc/spark/conf/spark-defaults.conf 中,将您的自定义 JAR 的路径附加到错误堆栈跟踪中指定的类名称。在以下示例中,/home/hadoop/extrajars/* 是自定义 JAR 路径。

sudo vim /etc/spark/conf/spark-defaults.conf

spark.driver.extraClassPath :/home/hadoop/extrajars/*
spark.executor.extraClassPath :/home/hadoop/extrajars/*

在新的集群上:

在创建集群时提供配置对象,从而在 /etc/spark/conf/spark-defaults.conf 中将自定义 JAR 路径附加到现有类路径中。

注意: 要使用此选项,您必须使用 Amazon EMR 发行版本 5.14.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/*"
    }
  }
]

对于单个作业:

使用 --jars 选项在您运行 spark-submit 时传入自定义 JAR 路径。示例:

spark-submit --deploy-mode client --class org.apache.spark.examples.SparkPi --master yarn spark-examples.jar 100 --jars /home/hadoop/extrajars/*

注意:要防止类冲突时,请勿在使用 --jars 选项时包含标准 JAR。例如,请勿包含 spark-core.jar,因为它已经存在于集群中。

有关配置分类的更多信息,请参阅配置 Spark