在 standalone cluster mode 中使用 apache spark 1.6 ,在具有 Windows 7 OS 的 single machine 中使用 Master 和 few Workers .
我在java应用程序中创建了spark上下文并编写了几个类(例如 MyFunction ,扩展了 org.apache.spark.api.java.function.Function )以便对数据执行转换 . 我称之为
javaRDD.map(new MyFunction());
Unfortunately ,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)
Questions:
-
如何从Spark Driver Program向Spark Worker提供应用程序自己的类文件
-
如果我需要向Spark Driver Program提供我的应用程序jar,我该怎么做呢 . (如上所述,sparkConf.setJars()方法对我来说失败了)
1 回答
对1和2的简短回答是,您可以通过创建将在驱动程序和工作程序上使用的胖/超级jar来简化代码的打包(驱动程序代码和工作程序所需的内容) .
正如'Submitting Applications'页面(http://spark.apache.org/docs/latest/submitting-applications.html)所述,解决这些问题的方法是构建项目的代码,将其与所有依赖项捆绑在一个jar文件中,然后可以像在代码中一样设置 .
从那个页面:
如果您的代码依赖于其他项目,则需要将它们与应用程序一起打包,以便将代码分发到Spark集群 . 为此,请创建包含代码及其依赖项的程序集jar(或“uber”jar) . sbt和Maven都有汇编插件 . 在创建程序集jar时,将Spark和Hadoop列为提供的依赖项;这些不需要捆绑,因为它们是由集群管理器在运行时提供的 . 一旦你有一个组装的jar,你可以在传递你的jar时调用bin / spark-submit脚本,如下所示 .
然后,您可以使用胖 jar 来运行驱动程序并提供工作人员所需的所有类 .
UPDATE (在评论中给出详细信息):当您将Web应用程序部署到应用程序服务器时,解决此问题的最佳方法是(IMO):
构建项目以从Spark客户端代码中拆分特定于Web的代码(驱动程序和工作人员的代码)
使Web项目依赖于spark客户端Jar,然后在调用setJars()时使用JAR文件 .
这可以做到如下:
Create JAR maven project to be used for spark-related code
Create a web project that depends on the previous artifact
Note that you may need to re-add here spark dependencies as they are marked as 'provided' in the dependency, but may actually be needed at runtime.
现在,您的Sark驱动程序代码必须位于Web项目中,因为它是预期运行驱动程序的代码(如您所建议的那样) .
有了这一切,您需要做的就是使用com.company.foo:foo-spark-client工件的uber jar路径调用setJars . 这个jar将在foo-spark-client项目的目标文件夹中创建(名称附加'-fat.jar') . 将此JAR放在运行Tomcat的服务器上的可访问路径上,然后相应地更新您的Web代码: