我正在研究基于Java的Spark Streaming应用程序,该应用程序响应通过Kafka主题发出的消息。对于每条消息,应用程序都会进行一些处理,并将结果写回不同的Kafka主题。
有时由于意外的数据相关问题,在RDD上运行的代码可能会失败并引发异常。当发生这种情况时,我希望有一个通用的处理程序,可以采取必要的操作并将消息发送到错误主题。现在,这些异常是由Spark本身在Spark的日志中写的。
执行此操作的最佳方法是什么,而不是为每个处理RDD的代码块编写try-catch块?
答案 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
}
}
}