Java 解决apachespark中的依赖性问题

Java 解决apachespark中的依赖性问题,java,scala,apache-spark,classnotfoundexception,nosuchmethoderror,Java,Scala,Apache Spark,Classnotfoundexception,Nosuchmethoderror,构建和部署Spark应用程序时的常见问题有: java.lang.ClassNotFoundException 对象x不是包y的成员编译错误 java.lang.NoSuchMethodError 如何解决这些问题?在构建和部署Spark应用程序时,所有依赖项都需要兼容版本 Scala版本。所有软件包都必须使用相同的主要(2.10、2.11、2.12)Scala版本 考虑以下内容(不正确)build.sbt: name := "Simple Project" version := "1.

构建和部署Spark应用程序时的常见问题有:

  • java.lang.ClassNotFoundException
  • 对象x不是包y的成员
    编译错误
  • java.lang.NoSuchMethodError

如何解决这些问题?

在构建和部署Spark应用程序时,所有依赖项都需要兼容版本

  • Scala版本。所有软件包都必须使用相同的主要(2.10、2.11、2.12)Scala版本

    考虑以下内容(不正确)
    build.sbt

    name := "Simple Project"
    
    version := "1.0"
    
    libraryDependencies ++= Seq(
       "org.apache.spark" % "spark-core_2.11" % "2.0.1",
       "org.apache.spark" % "spark-streaming_2.10" % "2.0.1",
       "org.apache.bahir" % "spark-streaming-twitter_2.11" % "2.0.1"
    )
    
    我们对Scala 2.10使用
    spark streaming
    ,而其余的包则用于Scala 2.11。可以创建一个有效的文件

    name := "Simple Project"
    
    version := "1.0"
    
    libraryDependencies ++= Seq(
       "org.apache.spark" % "spark-core_2.11" % "2.0.1",
       "org.apache.spark" % "spark-streaming_2.11" % "2.0.1",
       "org.apache.bahir" % "spark-streaming-twitter_2.11" % "2.0.1"
    )
    
    name := "Simple Project"
    
    version := "1.0"
    
    libraryDependencies ++= Seq(
       "org.apache.spark" % "spark-core_2.11" % "2.0.1",
       "org.apache.spark" % "spark-streaming_2.10" % "2.0.1",
       "org.apache.bahir" % "spark-streaming-twitter_2.11" % "2.0.1"
    )
    
    但最好全局指定版本,并使用
    %%
    (为您添加scala版本):

同样,在Maven中: 我们使用
spark-core
1.6,其余部件使用spark-2.0。可以创建一个有效的文件

name := "Simple Project"

version := "1.0"

libraryDependencies ++= Seq(
   "org.apache.spark" % "spark-core_2.11" % "2.0.1",
   "org.apache.spark" % "spark-streaming_2.11" % "2.0.1",
   "org.apache.bahir" % "spark-streaming-twitter_2.11" % "2.0.1"
)
name := "Simple Project"

version := "1.0"

libraryDependencies ++= Seq(
   "org.apache.spark" % "spark-core_2.11" % "2.0.1",
   "org.apache.spark" % "spark-streaming_2.10" % "2.0.1",
   "org.apache.bahir" % "spark-streaming-twitter_2.11" % "2.0.1"
)
但是最好使用一个变量 (仍然不正确):

同样,在Maven中:

com.example
简单项目
4.0.0
简单项目
罐子
1
2.0.1
2.11
org.apache.spark
spark-core{scala.version}
${spark.version}
org.apache.spark
spark-streaming_${scala.version}
${spark.version}
org.apache.bahir
spark-streaming-twitter_${scala.version}
${spark.version}
  • Spark dependencies中使用的Spark版本必须与Spark安装的Spark版本匹配。例如如果在集群上使用1.6.1,则必须使用1.6.1来构建JAR。次要版本不匹配并不总是被接受

  • 用于构建jar的Scala版本必须与用于构建已部署Spark的Scala版本匹配。默认情况下(可下载的二进制文件和默认版本):

    • Spark 1.x->Scala 2.10
    • Spark 2.x->Scala 2.11
  • 如果fat jar中包含其他包,那么应该可以在worker节点上访问这些包。有多种选择,包括:

    • --jars
      用于
      spark submit
      -分发本地
      jar
      文件的参数
    • --用于
      spark submit
      的packages
      参数,用于从Maven存储库获取依赖项
    在集群节点中提交时,您应该在
    --jars
    中包含应用程序
    jar


除了用户7337271已经给出的非常广泛的答案之外,如果问题是由于缺少外部依赖项造成的,您可以使用您的依赖项构建一个jar,例如


在这种情况下,请确保将构建系统中的所有核心spark依赖项标记为“已提供”,并如前所述,确保它们与运行时spark版本相关。

应用程序的依赖类应在启动命令的应用程序jar选项中指定

有关更多详细信息,请访问

摘自文件:

applicationjar:绑定jar的路径,包括您的应用程序和 所有依赖项。URL必须在您的网站中全局可见 集群,例如,一个hdfs://路径或一个文件://路径 存在于所有节点上


ApacheSpark的类路径是动态构建的(以适应每个应用程序用户代码),这使得它容易受到此类问题的攻击。”s的答案是正确的,但还有一些问题,这取决于您使用的群集管理器(“主”)

首先,Spark应用程序由以下组件组成(每个组件都是单独的JVM,因此在其类路径中可能包含不同的类):

  • 驱动程序:这是您的应用程序创建的
    SparkSession
    (或
    SparkContext
    )并连接到群集管理器以执行实际工作
  • 群集管理器:充当群集的“入口点”,负责为每个应用程序分配执行器。Spark支持几种不同的类型:standalone、Thread和Mesos,我们将在下面介绍它们
  • 执行者:这些是群集节点上执行实际工作(运行Spark任务)的进程
  • ApacheSpark的图中描述了它们之间的关系:

    现在-每个组件中应该驻留哪些类?

    这可以通过下图来回答:

    让我们慢慢分析一下:

  • Spark代码是Spark的库。它们应该存在于所有三个组件中,因为它们包括让Spark执行它们之间通信的胶水。顺便说一句,Spark的作者做出了一个设计决策,在所有组件中包含所有组件的代码(例如,在驱动程序中也包含只应在Executor中运行的代码),以简化这一点——因此Spark的“胖罐子”(在1.6之前的版本中)或“归档”(在2.0中,详细信息如下)包含所有组件的必要代码,并且应该在所有组件中都可用

  • 仅驱动程序代码这是不包括应在执行器上使用的任何内容的用户代码,即未在RDD/DataFrame/Dataset上的任何转换中使用的代码。这不一定要与分布式用户代码分开,但可以分开

  • 分布式代码这是使用驱动程序代码编译的用户代码,但也必须在执行器上执行-实际转换使用的所有内容都必须包含在此jar中

  • 既然我们已经弄清楚了,我们如何正确加载类
    name := "Simple Project"
    
    version := "1.0"
    
    libraryDependencies ++= Seq(
       "org.apache.spark" % "spark-core_2.11" % "2.0.1",
       "org.apache.spark" % "spark-streaming_2.10" % "2.0.1",
       "org.apache.bahir" % "spark-streaming-twitter_2.11" % "2.0.1"
    )
    
    name := "Simple Project"
    
    version := "1.0"
    
    val sparkVersion = "2.0.1"
    
    libraryDependencies ++= Seq(
       "org.apache.spark" % "spark-core_2.11" % sparkVersion,
       "org.apache.spark" % "spark-streaming_2.10" % sparkVersion,
       "org.apache.bahir" % "spark-streaming-twitter_2.11" % sparkVersion
    )
    
        <project>
          <groupId>com.example</groupId>
          <artifactId>simple-project</artifactId>
          <modelVersion>4.0.0</modelVersion>
          <name>Simple Project</name>
          <packaging>jar</packaging>
          <version>1.0</version>
          <properties>
            <spark.version>2.0.1</spark.version>
            <scala.version>2.11</scala.version>
          </properties> 
          <dependencies>
            <dependency> <!-- Spark dependency -->
              <groupId>org.apache.spark</groupId>
              <artifactId>spark-core_${scala.version}</artifactId>
              <version>${spark.version}</version>
            </dependency>
            <dependency>
              <groupId>org.apache.spark</groupId>
              <artifactId>spark-streaming_${scala.version}</artifactId>
              <version>${spark.version}</version>
            </dependency> 
            <dependency>
              <groupId>org.apache.bahir</groupId>
              <artifactId>spark-streaming-twitter_${scala.version}</artifactId>
              <version>${spark.version}</version>
            </dependency>
          </dependencies>
        </project>
    
    lazy val root = (project in file(".")).
      settings(
        name := "spark-samples",
        version := "1.0",
        scalaVersion := "2.11.12",
        mainClass in Compile := Some("StreamingExample")        
      )
    
    libraryDependencies ++= Seq(
      "org.apache.spark" %% "spark-core" % "2.4.0",
      "org.apache.spark" %% "spark-streaming" % "2.4.0",
      "org.apache.spark" %% "spark-sql" % "2.4.0",
      "com.couchbase.client" %% "spark-connector" % "2.2.0" 
    )
    
    // META-INF discarding
    assemblyMergeStrategy in assembly := {
           case PathList("META-INF", xs @ _*) => MergeStrategy.discard
           case x => MergeStrategy.first
       }
    
    java.lang.NoClassDefFoundError: rx/Completable$OnSubscribe
        at com.couchbase.spark.connection.CouchbaseConnection.streamClient(CouchbaseConnection.scala:154)
    
    jar tf target/scala-2.11/spark-samples-assembly-1.0.jar | grep 'Completable$OnSubscribe'
    rx/Completable$OnSubscribe.class