Kafka Streams 任务分配

Kafka Streams task assignment

我有一个 Kafka-Streams 应用程序 运行 一个线程,用一个分区处理一个主题就好了。

我需要 运行 此应用程序的多个实例同时处理不同的主题。在我目前的场景中,所有主题只有一个分区。

当我 运行 同一应用程序的新实例(具有相同的 APPLICATION_ID),处理不同的主题时,Streams 客户端不会不要在此新应用程序中创建新任务。第一个实例继续处理任务中的第一个主题 0_0,第二个实例在没有分配分区的情况下等待。

我知道我只使用一个分区的主题,但在这种情况下,如果我有两个实例和两个主题,一个分区要处理,这就形成了两个分区,为什么不能两个主题都使用它们的单个分区在每个实例中同时处理?

我怀疑它与 StreamsPartitionAssignor 有关,但在 Kafka Streams 应用程序中无法更改分配策略:

Kafka Streams does not allow to use a custom partition assignor. If you set one yourself, it will be overwritten with the StreamsPartitionAssignor [1]. This is needed to ensure that -- if possible -- partitions are re-assigned to the same consumers (a.k.a. stickiness) during rebalancing.

编辑:

应用程序的拓扑结构:

[2019-11-20 09:36:35,406] [INFO] stream-thread [avro-to-json-d07ad9ad-f4b6-4787-96cf-19c48e72ad46-StreamThread-1] Starting (org.apache.kafka.streams.processor.internals.StreamThread)
[2019-11-20 09:36:35,407] [INFO] stream-thread [avro-to-json-d07ad9ad-f4b6-4787-96cf-19c48e72ad46-StreamThread-1] State transition from CREATED to RUNNING (org.apache.kafka.streams.processor.internals.StreamThread)
[2019-11-20 09:36:35,407] [INFO] stream-client [avro-to-json-d07ad9ad-f4b6-4787-96cf-19c48e72ad46] Started Streams client (org.apache.kafka.streams.KafkaStreams)
Topologies:
   Sub-topology: 0
    Source: KSTREAM-SOURCE-0000000000 (topics: [])
      --> KSTREAM-MAP-0000000001
    Processor: KSTREAM-MAP-0000000001 (stores: [])
      --> KSTREAM-MAP-0000000002
      <-- KSTREAM-SOURCE-0000000000
    Processor: KSTREAM-MAP-0000000002 (stores: [])
      --> KSTREAM-TRANSFORM-0000000003
      <-- KSTREAM-MAP-0000000001
    Processor: KSTREAM-TRANSFORM-0000000003 (stores: [])
      --> KSTREAM-SINK-0000000004
      <-- KSTREAM-MAP-0000000002
    Sink: KSTREAM-SINK-0000000004 (extractor class: kafka.AvroToJson$$Lambda/741730375@957e06)
      <-- KSTREAM-TRANSFORM-0000000003

如果我对你的理解正确的话,你 运行 两个 Streams 客户端具有相同的 application.id 除了输入主题之外具有相同的拓扑结构。这意味着由于不同的输入主题,您实际上 运行 两个不同的 Streams 应用程序与您的 Streams 客户端。 运行 具有相同 application.id 的两个不同的 Streams 应用程序是未定义的行为,因为 application.id 需要在 Kafka 集群中是唯一的(参见 https://kafka.apache.org/23/documentation/#streamsconfigs)。

您可以

  1. 增加其中一个主题的分区并将该主题用作两个 Streams 应用程序中的输入主题(使它们成为同一个应用程序),或者
  2. 更改两个应用之一的 application.id

请注意,选项 1 可以让您自动重新平衡 Streams 客户端之间的工作负载,而选项 2 则不能。