Spark中未捕获的异常处理

时间:2015-10-21 14:42:35

标签: apache-spark spark-streaming

我正在研究基于Java的Spark Streaming应用程序,该应用程序响应通过Kafka主题发出的消息。对于每条消息,应用程序都会进行一些处理,并将结果写回不同的Kafka主题。

有时由于意外的数据相关问题,在RDD上运行的代码可能会失败并引发异常。当发生这种情况时,我希望有一个通用的处理程序,可以采取必要的操作并将消息发送到错误主题。现在,这些异常是由Spark本身在Spark的日志中写的。

执行此操作的最佳方法是什么,而不是为每个处理RDD的代码块编写try-catch块?

2 个答案:

答案 0 :(得分:4)

您可以编写执行此操作的通用函数。您只需将其包装在RDD操作中,因为这些操作是唯一可以抛出Spark异常的操作(像.map.filter这样的变换器是由操作执行的延迟执行)。

(假设这是在Scala中)你甚至可以尝试使用含义。创建一个包含RDD的类并处理错误。这里有一个可能的样子草图:

implicit class FailSafeRDD[T](rdd: RDD[T]) {
  def failsafeAction[U](fn: RDD[T] => U): Try[U] = Try {
    fn(rdd)
  }
}

您可以将错误主题消息添加到failsafeAction或每次失败时要执行的任何操作。然后用法可能就像:

val rdd = ??? // Some rdd you already have
val resultOrException = rdd.failsafeAction { r => r.count() }

除此之外,我想象最好的"方法对于应用需求有点主观。

答案 1 :(得分:2)

我认为您也可以使用try catch =>

来实现这一点
dstream.foreachRDD { case rdd: RDD[String] => 
    rdd.foreach { case string: String => 
      try {
        val kafkaProducer = ...
        val msg = ...
        kafkaProducer.send(msg)
      } catch {
        case d: DataException=>
          val kafkaErrorProducer = ...
          val errorMsg = ...
          kafkaErrorProducer.send(errorMsg )
        case t: Throwable =>
          //further error handling
      }
   }
}