我有一个Spark Streaming应用程序,它从Kafka中读取记录。我希望它可以按照以下算法工作:
该算法是通过异常处理实现的(我不知道是否有更好的方法可以做到,但这就是我的做法):
val kafkaParams = Map(
"metadata.broker.list" -> (currentHost + ":" + kafkaBrokerPort.toString),
"auto.offset.reset" -> "smallest",
"enable.auto.commit" -> "true",
"group.id" -> "test"
)
try {
val lines = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder, (String, String)](
ssc, kafkaParams, fromOffsets, messageHandler)
processKafkaStream(lines)
}
catch {
case _: kafka.common.OffsetOutOfRangeException =>
val lines = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](
ssc, kafkaParams, topics)
processKafkaStream(lines)
}
(在上述fromOffsets中的代码中,类型为Map [TopicAndPartition,Long]; Long是我从外部数据库获取的偏移量的值。)
我面临的问题如下: 如果我提供的起始偏移量太小而Kafka引发异常,则应用程序会处理该异常,但是与其从头开始读取主题并将其全部内容保存为HDFS的第一批内容,它仅创建一个目录,其中包含空文件HDFS为第一个批次,然后继续添加新数据作为其他批次。
Kafka中的主题有很多数据,因此我绝对希望第一批文件很大。相反,我得到的文件_SUCCESS和part-00000都为空。
如果我尝试在没有异常处理和相同kafkaParams的情况下实现应用程序,则会在第一批中确实从该主题获取所有数据,但是我需要一种算法,该算法可以让我从特定偏移量读取Kafka。
因此,问题是:为什么我将空文件作为第一批而不是主题的全部内容?有没有办法使其与上述算法兼容?
环境:
斯卡拉:2.11.8
火花:2.3.1
卡夫卡:1.0.1