我已经在 spark 中实现了一些逻辑。此逻辑的执行取决于传递给 Java 代码的参数。在我的主要方法中,我有一个开关盒。当我传递正确的参数时,一切正常。当我传递一些不在我的开关盒中的随机参数时,我得到了 Spark 异常。已完成,状态为失败。
如果我在客户端模式下运行相同的代码,它不会抛出任何参数不正确的异常,我认为这是正确的行为。
只有当我的参数正确时,我才会创建上下文。所以基本上,如果我在集群模式下提供一个空的 main 方法,我就会遇到异常。
谁能解释一下这是如何工作的。我怎样才能避免这个异常。
public class MyClass{
private JavaSparkContext context = null;
private HiveContext hiveContext = null;
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.startProcessing(args);
}
简单的 startProcessing 方法包含一个 switch case。
谢谢
堆栈跟踪:
Exception in thread "main" org.apache.spark.SparkException: Application application_1466638963111_3824 finished with failed status
at org.apache.spark.deploy.yarn.Client.run(Client.scala:1036)
at org.apache.spark.deploy.yarn.Client$.main(Client.scala:1083)
at org.apache.spark.deploy.yarn.Client.main(Client.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:731)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:181)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:206)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
最佳答案
当您在“客户端”模式下运行应用程序时,用于运行应用程序的脚本(我认为是 bin/spark-submit)会直接启动您的主类。您的 Main 类必须创建 Spark 上下文,如果您使用 Mesos 或 Yarn 之类的,该 Spark 上下文将连接到 Spark 集群或集群管理器。在这种情况下,如果您不创建 Spark 上下文就可以了。您的主类什么也不做就退出。
在集群模式下,Spark 不会直接运行您的主类,它会创建一个客户端并创建提交请求并将此请求提交给集群。此提交请求将您的主类名称作为参数。当集群收到此请求时,它会启动您的主类。客户端此时正在等待集群响应Spark上下文创建成功,客户端需要获取创建上下文的信息。
但是,如果您不创建上下文,客户端将无法连接到它,并且客户端不会收到上下文已成功创建的响应并抛出异常。
还可以添加
--verbose
标记您的启动脚本,您会看到在客户端模式下它直接启动您的主类,而在集群模式下它启动不同的主类。
关于java - 当 main 方法什么都不做时,集群模式下的 Spark 提交失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38134851/