我正在使用直接方法使用Kafka的Spark Streaming。基本上,当批次级别的某些重试后有多个任务失败时,整个批次失败并且数据丢失。我想知道是否有任何机制跟踪丢失的偏移范围的失败批次,以便我可以再次重新处理这些丢失的数据。
答案 0 :(得分:1)
Spark流式偏移提交在检查指向处完成。但使用检查指向几乎没有问题。一个人无法处理消息但是提交了偏移量。此外,您的火花输出系统应该是幂等的。
因此,最好将偏移存储在某些分布式存储中,如HBase,zookeeper。 为此,当消息由spark处理时,必须将偏移存储到外部存储器。有两种方式。
1.使用kafka的commitAsync(offsetRanges)。这是在spark处理msg之后完成的。在这种情况下,您的系统需要是幂等的,因为可能会出现两次最终处理相同的消息的情况。考虑到提交偏移时的情况,您的应用程序崩溃了。
例如。摘自spark doc。
stream.foreachRDD { rdd =>
val offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
// some time later, after outputs have completed
stream.asInstanceOf[CanCommitOffsets].commitAsync(offsetRanges)
}
2。使用事务来完成偏移。这样可以确保您的事务从保存spark进程开始,直到提交偏移量是以事务方式完成的。
例如。来自spark doc。
stream.foreachRDD { rdd =>
val offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
val results = yourCalculation(rdd)
// begin your transaction
// update results
// update offsets where the end of existing offsets matches the beginning of this batch of offsets
// assert that offsets were updated correctly
// end your transaction
}
您可以随时通过读取重启时createDirectStream参数中的存储和设置来设置偏移量,如下所示。
val stream = KafkaUtils.createDirectStream[String, String](
streamingContext,
PreferConsistent,
Assign[String, String](fromOffsets.keys.toList, kafkaParams, fromOffsets)
)