检查Spark流作业是否挂起的最佳方法

时间:2018-10-17 20:08:49

标签: apache-spark apache-spark-sql bigdata spark-streaming

我有一个Spark流媒体应用程序,该应用程序基本上从Kafka那里收到触发消息,它会启动批处理,这可能要花费2个小时。

有些事件会导致某些作业无限期地挂起,并且在通常的时间内没有完成,并且目前无法在不手动检查Spark UI的情况下找出作业状态。我希望有一种方法可以解决当前正在运行的Spark作业是否挂起的问题。因此,基本上,如果挂起超过30分钟,我想通知用户以便他们采取措施。我有什么选择?

我看到我可以使用驱动程序和执行程序中的指标。如果我选择最重要的记录,那将是最后收到的批记录。当StreamingMetrics.streaming.lastReceivedBatch_records == 0时,它可能意味着Spark流作业已停止或失败。

但是在我的情况下,我将仅收到1个流触发事件,然后它将启动处理过程,这可能需要2个小时,因此我将无法依赖收到的记录。

有更好的方法吗? TIA

7 个答案:

答案 0 :(得分:1)

YARN提供了REST API来检查应用程序状态和群集资源利用状态。

通过API调用,它将提供正在运行的应用程序及其启动时间和其他详细信息的列表。您可以有一个简单的REST客户端,它每30分钟左右触发一次,然后检查作业是否运行了2个小时以上,然后发送简单的邮件警报。

以下是API文档:

https://hadoop.apache.org/docs/r2.7.3/hadoop-yarn/hadoop-yarn-site/ResourceManagerRest.html#Cluster_Applications_API

答案 1 :(得分:0)

大约一年前,我遇到过类似的情况,这就是我所做的-

Kafka收到消息后,spark streaming作业将接收事件并开始处理。

Spark streaming作业向email发送警报Support group,提示“收到事件并触发转换STARTED”。 Start timestamp已存储。

完成火花处理/转换后-向支持小组发送警报email,提示“火花转换ENDED成功”。 End timestamp已存储。

以上两个步骤将帮助支持小组跟踪启动后是否未收到火花处理成功电子邮件,他们可以通过查看火花UI来调查作业失败或延迟处理(可能是由于资源长时间无法使用而导致作业挂起)时间)

最后-将事件ID或详细信息以及开始和结束时间戳记存储在HDFS文件中。并将此文件保存到某个配置单元HDFS指向的log_table路径中。这对于将来参考火花代码在这段时间内的性能很有帮助,如果需要,可以fine tuned

希望这会有所帮助。

答案 2 :(得分:0)

我目前正在与Google Spark Operator一起使用Kubernetes。 [1]

使用Spark 2.4.3时,我的某些流作业挂起:很少的任务失败,因此当前的批处理作业永远不会进行。

我使用StreamingProgressListener设置了超时时间,以便线程在很长时间内没有新批处理提交时发出信号。然后将信号转发到Pushover客户端,该客户端将通知发送到Android设备。然后调用System.exit(1)。 Spark操作员最终将重新启动作业。

[1] https://github.com/GoogleCloudPlatform/spark-on-k8s-operator

答案 3 :(得分:0)

一种方法是监视启动的火花作业的输出。通常,例如,

  • 如果它写入HDFS,请在HDFS输出目录中监视上次修改的文件时间戳或生成的文件计数
  • 如果它写入数据库,则可以进行查询以检查插入到作业输出表中的最后一条记录的时间戳。
  • 如果它写入Kafka,则可以使用Kafka GetOffsetShell获取输出主题的当前偏移量。

答案 4 :(得分:0)

也许是一个简单的解决方案。

在处理开始时-启动一个等待线程。

val TWO_HOURS = 2 * 60 * 60 * 1000

val t = new Thread(new Runnable {
  override def run(): Unit = {
    try {
      Thread.sleep(TWO_HOURS)
      // send an email that job didn't end
    } catch {
      case _: Exception => _
    }
  }
})

在可以说批处理结束的地方

t.interrupt()

如果处理在2小时内完成-服务线程中断并且不发送电子邮件。如果未完成处理-将发送电子邮件。

答案 5 :(得分:0)

利用 TaskContext

这提供了任务的上下文信息,并支持为任务完成/失败添加侦听器(请参阅addTaskCompletionListener)。

还有更多详细信息,例如任务“ attemptNumber”或“ taskMetrics”。

您的应用程序可以在运行时使用此信息来确定它们是否为“挂起”(取决于问题)

有关“挂起”的更多信息将有助于提供更具体的解决方案。

答案 6 :(得分:0)

让我引起您对Streaming Query侦听器的注意。这些都是非常惊人的轻量级功能,可以监视您的流式查询进度。

在具有多个查询的应用程序中,您可以找出哪些查询因某些异常而滞后或已停止。

请找到以下示例代码以了解其实现。我希望您可以使用它并将其转换为更适合您的需求。谢谢!

spark.streams.addListener(new StreamingQueryListener() {
    override def onQueryStarted(event: QueryStartedEvent) {
      //logger message to show that the query has started
    }
    override def onQueryProgress(event: QueryProgressEvent) {
      synchronized {
        if(event.progress.name.equalsIgnoreCase("QueryName"))
        {
        recordsReadCount = recordsReadCount + event.progress.numInputRows
        //Logger messages to show continuous progress
        }
      }
    }
    override def onQueryTerminated(event: QueryTerminatedEvent) {
      synchronized {
        //logger message to show the reason of termination.
      }
    }
  })