使用 Kafka Streams 分配多个主题的消费者

Consumer assignment with multiple topics with Kafka Streams

抱歉,如果之前已经介绍过,我找不到任何密切相关的内容。我有这个 Kafka Streams 应用程序,它从多个主题中读取数据,将记录保存在数据库中,然后将事件发布到输出主题。非常简单,就卡夫卡本地商店而言,它是无状态的。 (拓扑如下)

Topic1(T1) 有 5 个分区,Topic2(T2) 有一个分区。这里的问题是,从两个主题消费时,如果我想 "full speed" 使用 T1(5 个消费者),它不能保证我将为 T1 上的每个分区都有专门的消费者。它将分布在两个主题分区中,我最终可能会得到不平衡的消费者(和空闲消费者),如下所示:

话虽如此:

  1. 拥有一个从同一 KafkaStreams 实例中的多个主题读取的拓扑是一种好习惯吗?

  2. 如果我想为T1 go "full speed",有什么方法可以实现像下面这样的分区分配吗? [c1: t1p1, t2p1], [c2: t1p2], [c3: t1p3], [c4: t1p4], [c5: t1p5]

  3. 下面哪种拓扑最适合我想要实现的目标?还是完全不相关?

选项 A(当前拓扑)

Topologies:
   Sub-topology: 0
    Source: topic1-source (topics: [TOPIC1])
      --> topic1-processor
    Processor: topic1-processor (stores: [])
      --> topic1-sink
      <-- topic1-source
    Sink: topic1-sink (topic: OUTPUT-TOPIC)
      <-- topic1-processor

  Sub-topology: 1
    Source: topic2-source (topics: [TOPIC2])
      --> topic2-processor
    Processor: topic2-processor (stores: [])
      --> topic2-sink
      <-- topic2-source
    Sink: topic2-sink (topic: OUTPUT-TOPIC)
      <-- topic2-processor

选项 B:

Topologies:
   Sub-topology: 0
    Source: topic1-source (topics: [TOPIC1])
      --> topic1-processor
    Source: topic2-source (topics: [TOPIC2])
      --> topic2-processor
    Processor: topic1-processor (stores: [])
      --> response-sink
      <-- topic1-source
    Processor: topic2-processor (stores: [])
      --> response-sink
      <-- topic2-source
    Sink: response-sink (topic: OUTPUT-TOPIC)
      <-- topic2-processor, topic1-processor
  1. 如果我对每个主题使用两个流,而不是对多个主题使用一个流,这对我想要实现的目标有用吗?
config1.put("application.id", "app1");
KakfaStreams stream1 = new KafkaStreams(config1, topologyTopic1);
stream1.start();

config2.put("application.id", "app2");
KakfaStreams stream2 = new KafkaStreams(config2, topologyTopic2);
stream2.start();

您描述的初始分配永远不会发生在 Kafka Streams 中(也不会发生在任何默认的 Consumer 配置中)。如果有 5 个分区并且您有 5 个消费者,则每个消费者将分配 1 个分区(对于具有自定义 PartitionAssignor 的普通消费者,您可以进行不同的分配,但所有默认实现都将确保适当的负载平衡)。

Is it a good practice having a topology that reads from multiple topics within the same KafkaStreams instance?

这没有问题。

Is there any way to achieve a partition assignment like the following if I want go "full speed" for T1? [c1: t1p1, t2p1], [c2: t1p2], [c3: t1p3], [c4: t1p4], [c5: t1p5]

根据您编写拓扑的方式,这将是 Kafka Streams 使用的开箱即用的分配。对于你的两个选项,选项 B 将导致此分配。

Which of the topologies below is most optimal to what I want to achieve? Or is it completely unrelated?

如上所述,选项 B 将导致上述分配。对于选项 A,您实际上甚至可以使用第 6 个实例,每个实例将只处理一个分区(因为有两个子拓扑,您将获得 6 个任务,5 个用于子拓扑 0,1 个用于子拓扑 1;子拓扑相互独立扩展);对于选项 A,您只能获得 5 个任务,因为只有一个子拓扑,因此两个输入主题的最大分区数(即 5)决定了任务数。

If I use two streams for each topic instead of a single streams with multiple topic, would that work for what I am trying to achieve?

是的,它与选项 A 基本相同——但是,您有两个消费者组,因此 "two application" 而不是一个。