Spark Streaming - 是否可以使用Kafka主题的特定分区?

时间:2016-10-13 15:28:43

标签: apache-kafka spark-streaming

我正在尝试使用Spark Streaming来使用Kafka主题的特定分区。

我在KafkaUtils类中没有看到任何针对此用例的方法。

有一种名为createRDD的方法,基本上期望offsets,它仅对非流应用程序有用。有没有其他方法可以使用Spark Streaming消耗Kafka主题的特定分区?

1 个答案:

答案 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 
}