Apache Spark Worker Nodes无法找到我的应用程序类

时间:2016-03-30 10:34:14

标签: java apache-spark apache-spark-mllib

独立群集模式中使用 apache spark 1.6 少数工作人员 单机 Windows 7操作系统

我在java应用程序中创建了spark上下文并编写了几个类(例如 MyFunction ,它扩展了 org.apache.spark.api.java.function.Function )以便执行数据转换。我称之为

javaRDD.map(new MyFunction());

很遗憾,Spark Workers找不到MyFunction类,并且使用ClassNotFoundException终止作业......

我做了一些研究,发现了一种方法 SparkConf.setJars(jars)。所以,我将我的应用程序构建到jar( myapp.jar )并将其放在一个目录中(例如 D:/ spark

String[] jars = { "file:D:/spark/myappjar" };
sparkConf.setJars(jars);

但它会导致例外:

2016-03-30 15:27:07 WARN  TaskSetManager:70 
- Lost task 0.0 in stage 0.0 (TID 0, alivia): 
java.lang.ClassNotFoundException: com.ai.cache.spark.NumericFieldsToVector
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:274)

问题:

  1. 如何将应用程序自己的类文件提供给Spark Spark Driver Program的工作人员

  2. 如果我需要向Spark Driver Program提供我的应用程序jar, 我怎样才能做到这一点。 (sparkConf.setJars()方法对我来说失败了 如上所述)

1 个答案:

答案 0 :(得分:0)

对1和2的简短回答是,您可以通过创建将在两者上使用的胖/超级jar来简化代码的打包(驱动程序代码和工作人员所需的内容)。司机和工人。

如“提交申请表”所述。在页面(http://spark.apache.org/docs/latest/submitting-applications.html)中,解决这些问题的方法是构建项目的代码,将其与所有依赖项捆绑在一个jar文件中,然后可以像在代码中那样设置。 / p>

从该页面开始:

如果您的代码依赖于其他项目,则需要将它们与应用程序一起打包,以便将代码分发到Spark群集。为此,请创建包含代码及其依赖项的程序集jar(或“uber”jar)。 sbt和Maven都有汇编插件。在创建程序集jar时,将Spark和Hadoop列为提供的依赖项;这些不需要捆绑,因为它们是由集群管理器在运行时提供的。一旦你有一个组装的jar,你可以在传递你的jar时调用bin / spark-submit脚本,如图所示。

然后,您可以使用胖罐运行驱动程序并提供工作人员所需的所有类。

更新(在评论中提供详细信息): 当您将Web应用程序部署到应用程序服务器时,解决此问题的最佳方法是(IMO):

  1. 构建项目以从Spark客户端代码(驱动程序和工作人员的代码)中分离特定于Web的代码
  2. 使Web项目依赖于spark客户端Jar,然后在调用setJars()时使用JAR文件。
  3. 可以这样做:

    创建用于与火花相关的代码的JAR maven项目

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.company.foo</groupId>
      <artifactId>foo-spark-client</artifactId>
      ...
      <!--Add spark-related dependencies as per your current setup-->
      <dependencies>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>${spark.version}</version>
            <scope>provided</scope>
        </dependency>
      <!-- Add the plugin to create the uber/fat jar file -->
      <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <artifactSet>
                            </artifactSet>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
      </build>
    

    创建一个依赖于上一个工件的Web项目

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.company.foo</groupId>
      <artifactId>foo-web</artifactId>
      <packaging>war</packaging>
      ...
      <!--Add spark client dependency -->
      <dependencies>
        <dependency>
            <groupId>com.company.foo</groupId>
            <artifactId>foo-spark-client</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    

    请注意,您可能需要在此处重新添加spark依赖项,因为它们被标记为&#39;提供&#39;在依赖项中,但实际上可能需要在运行时。

    现在,您的Sark驱动程序代码必须位于Web项目中,因为它是预期运行驱动程序的驱动程序(如您所建议的那样)。

    这一切你需要做的就是调用setJars,其中包含com.company.foo:foo-spark-client工件的uber jar路径。这个jar将在foo-spark-client项目的目标文件夹中创建(&#39; -fat.jar&#39;附加到名称)。将此JAR放在运行Tomcat的服务器上的可访问路径上,然后相应地更新您的Web代码:

    String[] jars = { "file:D:/foo-spark-client/target/foo-spark-client-1.0-SNAPSHOT-fat.jar" };
    sparkConf.setJars(jars);