Kafka 流中线程分配的策略是什么?

What is the strategy by thread assignment in Kafka streams?

我在代码中做了这样的设置:

// loop over the inTopicName(s) {

KStream<String, String> stringInput = kBuilder.stream( STRING_SERDE, STRING_SERDE, inTopicName );
stringInput.filter( streamFilter::passOrFilterMessages ).map( processor_i ).to( outTopicName );

// } end of loop

streams = new KafkaStreams( kBuilder, streamsConfig );
streams.cleanUp();
streams.start();

如果有,例如num.stream.threads > 1、如何将任务分配给prepared和assigned(in the loop)线程?

我想(我不确定)有线程池并且通过某种循环策略将任务分配给线程,但它可以在运行时完全动态地完成,或者在开始时通过创建filtering/mapping 结构。

我特别感兴趣的是,当一个主题正在执行计算密集型任务而其他主题不是。应用程序是否有可能饿死,因为所有线程都将分配给耗时的处理器。

让我们来玩一下场景:num.stream.threads=2,每个主题 no. partitions=4no. topics=2(huge_topic 和 slim_topic) 我的问题中的循环在应用程序启动时完成一次。如果在循环中我定义了 2 个主题,并且我知道一个主题来自一个权重较高的消息 (huge_topic),另一个来自轻量级消息 (slim_topic)。 来自 num.stream.threads 的两个线程是否可能只忙于来自 huge_topic 的任务?来自 slimm_topic 的消息必须等待处理?

If there is e.g. num.stream.threads > 1, how tasks are assigned to the prepared and assigned (in the loop) threads?

使用分区组 将任务分配给线程。你可以阅读它 here。据我所知,它是在重新平衡之后调用的,所以它不是一个非常动态的过程。也就是说,我认为没有饥饿的选择。

在内部,Kafka Streams 根据分区创建任务。以您的循环示例为例,假设您有 3 个输入主题 A、B、C,分别具有 2、4 和 3 个分区。为此,您将获得 4 个任务(即所有主题的最大分区数),任务分配的分区如下:

  • t0: A-0, B-0, C-0
  • t1: A-1, B-1, C-1
  • t2: B-2、C-2
  • t3: B-3

分区“按编号”分组并分配给相应的任务。这是在运行时确定的(即,在您调用 KafakStreams#start() 之后),因为在此之前,每个主题的分区数是未知的。

如果你不了解 Kafka Streams 的所有内部细节,不建议乱用分组的分区——你很容易破坏东西!(这个接口已被弃用,并将在即将发布的 3.0 版本中删除。)

关于线程:任务限制线程数。对于我们的示例,这意味着您最多可以有 4 个线程(如果有更多线程,这些线程将处于空闲状态,因为没有任务留给线程分配)。您如何“分发”这些线程取决于您。您可以拥有一个具有 4 个线程(或介于两者之间的任何线程)的单个应用程序实例的 4 个单线程应用程序实例。

如果您的任务比线程少,任务将根据任务数量以负载平衡的方式分配(假定所有任务具有相同的负载)。