为什么SparkLauncher会立即返回并且不会产生任何工作?

时间:2016-01-14 22:34:59

标签: java apache-spark spark-launcher

我在Spark v1.6.0中使用SparkLauncher。我的问题是,当我使用这个类启动我的Spark作业时,它立即返回并且没有提交作业。我的代码如下。

new SparkLauncher()
 .setAppName("test word count")
 .setAppResource("file://c:/temp/my.jar")
 .setMainClass("my.spark.app.Main")
 .setMaster("spark://master:7077")
 .startApplication(new SparkAppHandler.Listener() {
   @Override public void stateChanged(SparkAppHandle h) { }
   @Override public void infoChanged(SparkAppHandle h) { } 
  });

当我调试代码时,我注意到,令我惊讶的是,所有这些clazz确实使用spark-submit.cmd来调用脚本ProcessBuilder

[C:/tmp/spark-1.6.0-bin-hadoop2.6/bin/spark-submit.cmd, --master, spark://master:7077, --name, "test word count", --class, my.spark.appMain, C:/temp/my.jar]

但是,如果我直接在控制台上运行此命令(由ProcessBuilder运行的命令),则会提交Spark作业。关于发生了什么的任何想法?

还有另一种方法SparkLauncher.launch()可用,但javadocs说要避免使用这种方法。

知道发生了什么事吗?

3 个答案:

答案 0 :(得分:5)

如果它在控制台中有效但不能从您的程序中运行,您可能需要告诉SparkLauncher Spark主页所在的位置:

.addSparkArg("--verbose")

但可能还有其他问题。您可能希望使用以下命令捕获其他调试信息:

Map<String, String> env = Maps.newHashMap();
env.put("SPARK_PRINT_LAUNCH_COMMAND", "1");

new SparkLauncher(env)

将env对象传递给SparkLauncher构造函数:

Integer("1234")

答案 1 :(得分:3)

如何将new SparkLauncher()语句放在程序中?

如果主程序/单元测试在调用.startApplication()后立即完成,那么它创建的子进程也会终止。

您可以使用创建的句柄检查作业的状态

SparkAppHandle handle = new SparkLauncher()
    .setAppName("test word count")
    .setAppResource("file://c:/temp/my.jar")
    .setMainClass("my.spark.app.Main")
    .setMaster("spark://master:7077")
    .startApplication();

handle.getState();  // immediately returns UNKNOWN

Thread.sleep(1000); // wait a little bit...

handle.getState();  // the state may have changed to CONNECTED or others

我认为这是因为应用程序需要一定时间才能连接到主服务器,如果程序在建立连接之前结束,则不会提交任何作业。

答案 2 :(得分:3)

您需要等待启动器连接到驱动程序并获取应用程序ID和状态。为此你可以做while循环或类似的东西。 例如。

   while(!handle.getState().isFinal()) { 
   logger.info("Current state: "+ handle.getState()) 
   logger.info("App Id "+ handle.getAppId());
   Thread.sleep(1000L);
   // other stuffs you want to do 
   //
   }