我正在尝试使用Spark Streaming来使用Kafka主题的特定分区。
我在KafkaUtils类中没有看到任何针对此用例的方法。
有一种名为createRDD
的方法,基本上期望offsets
,它仅对非流应用程序有用。有没有其他方法可以使用Spark Streaming消耗Kafka主题的特定分区?
答案 0 :(得分:3)
没有一种方法可以使用单个分区,我们可以使用的最精细的是一个主题。但是,有一种方法可以指定给定的消息来自特定分区。您可以在使用createDirectStream
的重载时执行此操作,该重载需要Function1[MessageAndMetadata, R]
。
例如,我们假设我们有一个类型为String
的密钥和消息,而且我们目前只使用一个主题消费。我们可以这样做:
val topicAndPartition: Map[TopicAndPartition, Long] = ???
val kafkaProperties: Map[String, String] = ???
KafkaUtils.createDirectStream[String,
String,
StringDecoder,
StringDecoder,
(String, String)](
streamingContext,
kafkaConfig.properties,
topicAndPartition,
(mam: MessageAndMetadata[String, String]) =>
(mam.partition, mam.message())
这样,我输出了分区(1)的元组和基础消息(2)。然后,我可以过滤此DStream[(String, String)]
以仅包含来自特定分区的消息:
val filteredStream = kafkaDStream.filter { case (partition, _) => partition == 4 }
如果我们从多个主题消费,我们需要输出主题和分区的元组,以便使用正确的主题过滤分区。幸运的是,我们可以使用一个名为TopicAndPartition
的便捷案例类。我们有:
(mam: MessageAndMetadata[String, String]) =>
(TopicAndPartition(mam.topic(), mam.partition()), mam.message())
然后:
val filteredStream = kafkaDStream.filter {
case (tap, _) => tap.topic == "mytopic" && tap.partition == 4
}