我有简单的火花流应用程序,它从Kafka读取数据,然后在http端点(或另一个kafka)上转换后发送这些数据 - 对于这个问题我们考虑使用http。我使用job-server提交工作。
我目前正从源kafka开始使用“auto.offset.reset”=“最小”和间隔= 3s。在快乐的情况下,一切都很好。这是一段摘录:
kafkaInputDStream.foreachRDD(rdd => {
rdd.foreach(item => {
//This will throw exception if http endpoint isn't reachable
httpProcessor.process(item._1, item._2)
})
})
由于“auto.offset.reset”=“最小”,因此在一个作业中处理大约200K条消息。如果我停止http服务器中间作业(模拟POST中的某些问题)并且httpProcessor.process抛出异常,则该作业失败并且未处理的任何内容都将丢失。我看到它在此之后每3秒继续进行一次轮询。
所以我的问题是:
由于
答案 0 :(得分:3)
是的,您的假设是正确的,如果您的分区失败,其余的事件暂时不会被处理 。
但是,有很多参数可供您调整以获得所需的行为(如果使用DirectKafkaInputDStream)。
让我们先从" auto.offset.reset" ="最小" :这个参数告诉Kafka从一开始就没有存储为当前组提交。正如您所说,RDD在启动后包含大量消息,我假设您没有正确提交消息。如果你期望完全一次语义,你肯定应该考虑跟踪你的偏移,因为DirectKafkaStreamInput显然没有跟踪它。
预先指定起始偏移量,此DStream不负责提交偏移量,因此您可以完全控制一次
Comment in the DirectKafkaInputSream Branch 1.6
这就是说,每次重新启动流式传输作业时,您的邮件都会被重新处理。
如果提交已处理的偏移量并在启动时将其传递给InputDStream,则侦听器将从最后提交的偏移量继续。
关于背压,DirectKafkaInputDStream已使用RateController来估算一批应处理多少事件。
要使用它,您必须启用背压:
"spark.streaming.backpressure.enabled": true
您还可以限制" spark.streaming.kafka.maxRatePerPartition" 以添加批量大小的上限。
如果您想自己控制背压(并且可能会暂时停止消费者),您可能需要实施StreamingListener的某些方法并在工作中使用它。你可以,例如在每个完成的批处理之后决定是否使用StreamingListener停止流式传输作业。
答案 1 :(得分:1)
我认为Spring Cloud Stream可以解决您的问题。 卡夫卡是来源。 Spark Streaming是处理器。 Http是下沉的。 只有来自Kafka的输入,才会处理Spark Streaming。您无需停止或恢复Kafka的输入。 希望它有所帮助。