我正在使用Spark Kafka直接流式传输来自Kafka的消息。我想实现零消息丢失,重新启动spark后,它必须从Kafka读取丢失的消息。我正在使用检查点来保存所有读取偏移,以便下次spark将从存储的偏移量开始读取。这是我的理解。
我使用了下面的代码。我停下了火花,向卡夫卡发了几条消息。重新启动火花后,没有读取来自卡夫卡的错过信息。 Spark从kafka读取最新消息。如何阅读卡夫卡错过的消息?
val ssc = new StreamingContext(spark.sparkContext, Milliseconds(6000))
ssc.checkpoint("C:/cp")
val kafkaParams = Map[String, Object](
"bootstrap.servers" -> "localhost:9092",
"key.deserializer" -> classOf[StringDeserializer],
"value.deserializer" -> classOf[StringDeserializer],
"group.id" -> "use_a_separate_group_id_for_each_stream",
"auto.offset.reset" -> "latest",
"enable.auto.commit" -> (false: java.lang.Boolean)
)
val topics = Array("test")
val ssc = new StreamingContext(spark.sparkContext, Milliseconds(50))
val msgStream = KafkaUtils.createDirectStream[String, String](
ssc,
PreferConsistent,
Subscribe[String, String](topics, kafkaParams)
)
注意:应用程序日志会将auto.offset.reset显示为无,而不是最新。为什么?
WARN KafkaUtils: overriding auto.offset.reset to none for executor
SBT
scalaVersion := "2.11.8"
val sparkVersion = "2.2.0"
val connectorVersion = "2.0.7"
val kafka_stream_version = "1.6.3"
Windows:7
答案 0 :(得分:0)
如果您想阅读遗漏的消息,请尝试提交进程而不是检查点。
请理解,Spark无法读取带有属性的旧消息:
"auto.offset.reset" -> "latest"
试试这个:
val kafkaParams = Map[String, Object](
//...
"auto.offset.reset" -> "earliest",
"enable.auto.commit" -> (false: java.lang.Boolean)
//...
)
stream.foreachRDD { rdd =>
val offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
//Your processing goes here
//Then commit after completing your process.
stream.asInstanceOf[CanCommitOffsets].commitAsync(offsetRanges)
}
希望这有帮助。
答案 1 :(得分:0)
我建议不要依赖检查点,而是可以使用外部数据存储来保存已处理的Kafka消息偏移。请点击链接以获得一些见解。 https://blog.cloudera.com/blog/2017/06/offset-management-for-apache-kafka-with-apache-spark-streaming/