![](/img/trans.png)
[英]Spark job never progresses from ACCEPTED state and hangs with a status of UNDEFINED
[英]How to get spark job status from program?
我知道hadoop REST API通过程序提供对作业状态的访问。
同样有什么方法可以在程序中获得spark作业状态?
它不是类似于REST API,但你可以通过注册跟踪从应用程序内部的工作状态SparkListener
与SparkContext.addSparkListener
。 它是这样的:
sc.addSparkListener(new SparkListener {
override def onStageCompleted(event: SparkListenerStageCompleted) = {
if (event.stageInfo.stageId == myStage) {
println(s"Stage $myStage is done.")
}
}
})
有一个(几乎)未记录的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
您也可以在不使用Spark Job History服务器的情况下获得Spark作业状态。 您可以使用SparkLauncher 2.0.1(甚至Spark 1.6版本也可以)从Java程序启动Spark作业:
SparkAppHandle appHandle = sparkLauncher.startApplication();
您还可以向startApplication()方法添加侦听器:
SparkAppHandle appHandle = sparkLauncher.startApplication(sparkAppListener);
听众有两种方法可以告诉你工作状态的变化和信息的变化。
我使用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() {}
}
为Java提供答案。 在Scala中,使用SparkContext而不是JavaSparkContext几乎是相似的。
假设您有一个JavaSparkContext:
private final JavaSparkContext sc;
以下代码允许从Jobs和Stages选项卡获取所有信息:
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()
...你可以尝试找到更多有用的信息。
Spark UI上有(n)(几乎)未记录的REST API功能,可提供有关作业和性能的指标。
你可以用以下方式访问它:
http://<driverHost>:<uiPort>/metrics/json/
(UIPort默认为4040)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.