在Spark上下文中使用多个同时作业进行Spark 2作业监视(JobProgressListener)

时间:2016-12-02 15:41:58

标签: apache-spark apache-spark-2.0

在Spark 2.0.x上,我一直在使用JobProgressListener实现从我们的集群中实时检索作业/阶段/任务进度信息。我了解事件流的工作原理,并成功接收有关工作的更新。

我的问题是我们在同一个Spark上下文中同时运行了几个不同的提交,并且似乎无法区分哪个作业/阶段/任务属于每个提交。每个作业/阶段/任务都会收到一个唯一的ID,这很棒。但是,我正在寻找提交提交的方式" id"或"名称"将与收到的JobProgressListener事件对象一起返回。

我意识到" Job Group"可以在Spark上下文中设置,但如果多个作业同时在同一个上下文中运行,它们将被加扰。

我是否有办法潜入自定义属性,这些属性将与单个SQLContext的侦听器事件一起返回?通过这样做,我应该能够链接后续的Stage和Task事件并获得我需要的东西。

请注意:我没有使用spark-submit来完成这些工作。它们是使用对SparkSession / SQLContext的Java引用执行的。

感谢任何解决方案或想法。

1 个答案:

答案 0 :(得分:0)

我正在使用本地属性 - 可以在 onStageSubmit 事件期间从侦听器访问它。之后,我将使用相应的 stageId 来识别在该阶段执行的任务。

Future({
      sc.setLocalProperty("job-context", "second")
      val listener = new MetricListener("second")
      sc.addSparkListener(listener)
      //do some spark actions
      val df = spark.read.load("...")
      val countResult = df.filter(....).count()
      println(listener.rows)
      sc.removeSparkListener(listener)
    })

class MetricListener(name:String) extends SparkListener{

  var rows: Long = 0L
  var stageId = -1
  
  override def onStageSubmitted(stageSubmitted: SparkListenerStageSubmitted): Unit = {
    if (stageSubmitted.properties.getProperty("job-context") == name){
      stageId = stageSubmitted.stageInfo.stageId
    }
  }

  override def onTaskEnd(taskEnd: SparkListenerTaskEnd): Unit = {
    if (taskEnd.stageId == stageId)
      rows = rows + taskEnd.taskMetrics.inputMetrics.recordsRead
  }
  
}