Kafka Streams:使用相同的`application.id`来使用多个主题

时间:2017-12-27 18:35:54

标签: apache-kafka apache-kafka-streams

我有一个需要收听多个不同主题的应用程序;每个主题都有关于如何处理消息的单独逻辑。我曾想过为每个KafkaStreams实例使用相同的kafka属性,但是我得到的错误如下所示。

错误

java.lang.IllegalArgumentException: Assigned partition my-topic-1 for non-subscribed topic regex pattern; subscription pattern is my-other-topic

代码(kotlin)

class KafkaSetup() {
    companion object {
        private val LOG = LoggerFactory.getLogger(this::class.java)
    }

    fun getProperties(): Properties {
        val properties = Properties()
        properties.put(StreamsConfig.APPLICATION_ID_CONFIG, "my-app")
        return properties
    }

    private fun listenOnMyTopic() {
        val kStreamBuilder = KStreamBuilder()
        val kStream: KStream<String, String> = kStreamBuilder.stream("my-topic")

        kStream.foreach { key, value -> LOG.info("do stuff") }

        val kafkaStreams = KafkaStreams(kStreamBuilder, getProperties())
        kafkaStreams.start()
    }

    private fun listenOnMyOtherTopic() {
        val kStreamBuilder = KStreamBuilder()
        val kStream: KStream<String, String> = kStreamBuilder.stream("my-other-topic")

        kStream.foreach { key, value -> LOG.info("do other stuff") }

        val kafkaStreams = KafkaStreams(kStreamBuilder, getProperties())
        kafkaStreams.start()
    }
}

我发现这个reference表明你不能将application.id用于多个主题,但我发现很难找到支持它的参考文档。 application.id状态的documentation

  

流处理应用程序的标识符。在Kafka集群中必须是唯一的。它用作1)默认的client-id前缀,2)成员资格管理的group-id,3)changelog主题前缀。

问题

  1. 这个错误是什么意思,是什么导致它。
  2. 鉴于您可以使用相同的ID从多个主题分区中运行您的多个app应用实例,&#34; Kafka群集中必须是唯一的&#34; 是什么意思?
  3. 您是否可以使用相同的Kafka流application.id来启动列出不同主题的两个KafkaStreams?若然,怎么样?
  4. 详细信息: kafka 0.11.0.2

1 个答案:

答案 0 :(得分:15)

Kafka Streams通过分区进行扩展,而不是主题。因此,如果您使用相同的application.id启动多个应用程序,则它们必须与它们订阅的输入主题及其处理逻辑相同。该应用程序使用application.id作为group.id形成一个使用者组,因此输入主题的不同分区被分配给不同的实例。

如果您对 相同的 逻辑有不同的主题,则可以立即订阅 所有 主题(在每个实例中你开始)。缩放仍然基于分区。 (它基本上是&#34;合并&#34;您的输入主题。)

如果您想通过主题进行扩展和/或具有不同的处理逻辑,则必须对不同的Kafka Streams应用程序使用不同的application.id