Kafka Streams:多个主题的Stream Thread与Partition

时间:2019-10-28 07:46:44

标签: apache-kafka apache-kafka-streams

假设我有2个主题,分别是xyz1,xyz2,每个主题都有3个分区。如果我有一个具有3个线程的Kafka流应用程序,是否会发生以下情况?

Thread                  Partition
    1       xyz1-partition 0, xyz2-partition 2
    2       xyz1-partition 1, xyz2-partition 0
    3       xyz1-partition 2, xyz2-partition 1

相对于:

Thread                  Partition
    1       xyz1-partition 0, xyz2-partition 0
    2       xyz1-partition 1, xyz2-partition 1
    3       xyz1-partition 2, xyz2-partition 2

从本质上讲,一个线程在消耗来自2个不同主题的特定分区中的数据,并且分区号可以变化吗?假设我们使用低级处理器API

2 个答案:

答案 0 :(得分:2)

这种情况是否发生取决于您的拓扑。

实际上,流任务分配给流线程,而不是普通分区。每个任务可以处理一组分区。一组包含一个或多个分区。如果该组包含多个分区,它将始终包含不同主题的相同分区(即具有相同分区号的分区)。例如,一个组可以包含xyz1分区0,xyz2分区0,但不包含xyz1分区0,xyz2分区2。这假定不同的主题使用相同的分区策略。需要对不同主题的相同分区进行这种共同分区,例如,在联接的情况下,必须使用相同的流任务来处理具有相同键的记录,这与第二种情况类似。

如果您在第一个示例中假设每个分区由不同的流任务处理,即每个分区组包含一个分区,则可能会发生这种情况。

如果您假设每行上的两个分区都是由同一流任务处理的(即,两个分区都是同一分区组的一部分),则不会发生这种情况,因为分区组不能包含不同的分区。

有关分配策略的更多信息,请参见https://github.com/apache/kafka/blob/e4262471c9aee4a4c04dd04ebbdbdba7e3c5ead1/streams/src/main/java/org/apache/kafka/streams/processor/internals/StreamsPartitionAssignor.java#L297

说,实际上,有一种方法可以通过实现PartitionGrouper接口将不同的分区分配给同一任务。但是,此接口将在2.4中弃用,并在3.0中删除。参见https://cwiki.apache.org/confluence/display/KAFKA/KIP-528%3A+Deprecate+PartitionGrouper+configuration+and+interface

答案 1 :(得分:2)

这取决于

普通卡夫卡消费者:

Kafka消费者组由具有相同group.id的消费者/实例/进程池组成。id可以在同一台计算机上运行,​​也可以在分布式计算机上运行。 Kafka Consumer使用重新平衡在每个消费者上分配分区,而不会重叠,这意味着一个分区最多可以分配Consumer Group的一个消费者进程。

使用者也可以使用assign(Collection)手动分配特定的分区(类似于较早的“简单”使用者)。在这种情况下,动态分区分配和消费者组协调将被禁用

因此,如果在重新平衡时分区可以分配给任何线程。

enter image description here

Kafka流:

Kafka使用流任务作为逻辑单元来分配分区和并行化进程。 Kafka Stream根据流分区创建多个流任务,并为每个任务分配分区列表。 将任务分配给分区后,它将根据自己的拓扑结构坚持并管理并行性,因此无需手动干预即可独立并行处理流任务。

  

对PartitionGrouper接口进行分组的默认实现   通过分区ID进行分区。加入操作需要主题   的连接实体是共同分配的,即通过   相同的键,并具有相同的分区数。共分区   通过在加入的主题上使用相同数量的分区来确保,   以及使用序列化和Producer的默认分区程序。here

因此,在您的情况下,方案1是不可能的,而方案2是可能的。

enter image description here