我在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说要避免使用这种方法。
知道发生了什么事吗?
答案 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
//
}