我知道hadoop REST API可以通过程序访问作业状态。
同样有什么方法可以在程序中获得spark作业状态吗?
答案 0 :(得分:4)
它与REST API不相似,但您可以通过向SparkContext.addSparkListener
注册SparkListener
来跟踪应用程序内部的作业状态。它是这样的:
sc.addSparkListener(new SparkListener {
override def onStageCompleted(event: SparkListenerStageCompleted) = {
if (event.stageInfo.stageId == myStage) {
println(s"Stage $myStage is done.")
}
}
})
答案 1 :(得分:2)
有一个(n)(几乎)未记录的REST API功能,几乎可以提供您在Spark UI上看到的所有内容:
http://<sparkMasterHost>:<uiPort>/api/v1/...
对于本地安装,您可以从这里开始:
http://localhost:8080/api/v1/applications
您可以在此处找到可能的终点:https://github.com/apache/spark/blob/master/core/src/main/scala/org/apache/spark/status/api/v1/ApiRootResource.scala
答案 2 :(得分:1)
您也可以在不使用Spark Job History服务器的情况下获得Spark作业状态。您可以使用SparkLauncher 2.0.1(甚至Spark 1.6版本也可以)从Java程序启动Spark作业:
SparkAppHandle appHandle = sparkLauncher.startApplication();
您还可以将侦听器添加到startApplication()方法:
SparkAppHandle appHandle = sparkLauncher.startApplication(sparkAppListener);
侦听器有2个方法可以告知您有关工作状态更改和信息更改的信息。
我使用CountDownLatch实现,它按预期工作。这适用于SparkLauncher 2.0.1版,它也适用于Yarn-cluster模式。
...
final CountDownLatch countDownLatch = new CountDownLatch(1);
SparkAppListener sparkAppListener = new SparkAppListener(countDownLatch);
SparkAppHandle appHandle = sparkLauncher.startApplication(sparkAppListener);
Thread sparkAppListenerThread = new Thread(sparkAppListener);
sparkAppListenerThread.start();
long timeout = 120;
countDownLatch.await(timeout, TimeUnit.SECONDS);
...
private static class SparkAppListener implements SparkAppHandle.Listener, Runnable {
private static final Log log = LogFactory.getLog(SparkAppListener.class);
private final CountDownLatch countDownLatch;
public SparkAppListener(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void stateChanged(SparkAppHandle handle) {
String sparkAppId = handle.getAppId();
State appState = handle.getState();
if (sparkAppId != null) {
log.info("Spark job with app id: " + sparkAppId + ",\t State changed to: " + appState + " - "
+ SPARK_STATE_MSG.get(appState));
} else {
log.info("Spark job's state changed to: " + appState + " - " + SPARK_STATE_MSG.get(appState));
}
if (appState != null && appState.isFinal()) {
countDownLatch.countDown();
}
}
@Override
public void infoChanged(SparkAppHandle handle) {}
@Override
public void run() {}
}
答案 3 :(得分:1)
提供Java的答案。在Scala中,仅使用SparkContext而不是JavaSparkContext几乎是相似的。
假设您有一个JavaSparkContext:
private final JavaSparkContext sc;
以下代码允许从“工作和阶段”标签获取所有可用信息:
JavaSparkStatusTracker statusTracker = sc.statusTracker();
for(int jobId: statusTracker.getActiveJobIds()) {
SparkJobInfo jobInfo = statusTracker.getJobInfo(jobId);
log.info("Job " + jobId + " status is " + jobInfo.status().name());
log.info("Stages status:");
for(int stageId: jobInfo.stageIds()) {
SparkStageInfo stageInfo = statusTracker.getStageInfo(stageId);
log.info("Stage id=" + stageId + "; name = " + stageInfo.name()
+ "; completed tasks:" + stageInfo.numCompletedTasks()
+ "; active tasks: " + stageInfo.numActiveTasks()
+ "; all tasks: " + stageInfo.numTasks()
+ "; submission time: " + stageInfo.submissionTime());
}
}
不幸的是,其他所有内容只能从scala Spark Context访问,因此使用Java提供的结构可能会有些困难。
池列表: sc.sc()。getAllPools()
执行器内存状态: sc.sc()。getExecutorMemoryStatus()
执行者ID: sc.sc()。getExecutorIds()
存储信息: sc.sc()。getRddStorageInfo()
...您可以尝试在其中找到更多有用的信息。
答案 4 :(得分:0)
Spark UI上有(n)(几乎)未记录的REST API功能,可提供有关作业和性能的指标。
您可以通过以下方式访问它:
http://<driverHost>:<uiPort>/metrics/json/
(UIPort默认为4040)