我在Spark 2.2上使用Spark Structured流将文件从HDFS目录流式传输到Kafka主题。我想捕获我写给主题的数据的Kafka偏移量。
我正在使用
val write = jsonDF
.writeStream.format("kafka")
.option("checkpointLocation", Config().getString(domain + ".kafkaCheckpoint"))
.option("kafka.bootstrap.servers", Config().getString(domain + ".kafkaServer"))
.option("topic", Config().getString(domain + ".kafkaTopic"))
.start()
写信给卡夫卡。
当我利用
时spark.streams.addListener(new StreamingQueryListener() {
override def onQueryStarted(queryStarted: QueryStartedEvent): Unit = {
println("Query started: " + queryStarted.id)
}
override def onQueryTerminated(queryTerminated: QueryTerminatedEvent): Unit = {
println("Query terminated: " + queryTerminated.id)
}
override def onQueryProgress(queryProgress: QueryProgressEvent): Unit = {
println("Query made progress: " + queryProgress.progress)
}
})
捕获流的进度信息,检索到的信息与Kafka中创建的偏移量无关。
我认为这是因为流提供的信息实际上与我正在使用的文件流有关,与Kafka中写的内容无关。
有没有办法使用Spark Structure Streaming来捕获我们写入Kafka时生成的偏移信息?
添加示例:
在我创建主题之后,当我从源1运行三行数据时,我得到:
运行1:
Start Offset:null,End offset:{“logOffset”:0}
开始偏移:{“logOffset”:0},结束偏移:{“logOffset”:0}
Kafka Says:
ruwe:2:1
ruwe:1:1
ruwe:0:1
运行2;
Start Offset: {"logOffset":0}, End offset: {"logOffset":1}
Start Offset: {"logOffset":1}, End offset: {"logOffset":1}
Kafka Says:
ruwe:2:2
ruwe:1:2
ruwe:0:2
运行3:
Start Offset: {"logOffset":1}, End offset: {"logOffset":2}
Start Offset: {"logOffset":2}, End offset: {"logOffset":2}
Kafka Says:
ruwe:2:3
ruwe:1:3
ruwe:0:3
然后我使用来自不同来源的相同程序运行数据并收到
Start Offset: null, End offset: {"logOffset":0}
Start Offset: {"logOffset":0}, End offset: {"logOffset":0}
and of course Kafka continued to increment
这表明Spark报告的信息基于来源
我想知道目标中创建了什么。
答案 0 :(得分:1)
在阅读Spark Structure Streaming的代码后,特别是Kafka KafkaWriter,KafkaWriteTask和CachedKafkaProducer,Spark不会消耗回调中从KafkaProducer返回的偏移量。他们定义的回调只捕获异常。基于此,我会说在当前版本2.2中无法完成。
他们提供的信息是查询的来源,而不是目标。
答案 1 :(得分:0)
是否有一种方法可以使用Spark Structure Streaming捕获偏移量 我们写信给卡夫卡时产生的信息?
是的,在onQueryProgress
中,您需要查看StreamingQueryProgress.sources
Array[SourceProgress]
。它有两个字符串startOffset
和endOffset
,它们是您可以解析的JSON:
sparkSession.streams.addListener(new StreamingQueryListener {override def onQueryStarted(event: StreamingQueryListener.QueryStartedEvent): Unit = ???
override def onQueryProgress(event: StreamingQueryListener.QueryProgressEvent): Unit = {
val source = event.progress.sources.headOption
source.map(src => println(s"Start Offset: ${src.startOffset}, End offset: ${src.endOffset}"))
}
override def onQueryTerminated(event: StreamingQueryListener.QueryTerminatedEvent): Unit = ()
})
JSON具有以下结构:
"startOffset" : {
"topic-name" : {
"0" : 1,
"1" : 22,
"2" : 419,
}
},
"endOffset" : {
"topic-name" : {
"0" : 10,
"1" : 100,
"2" : 1000
}
}