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

时间:2017-10-09 09:25:53

标签: multithreading apache-kafka apache-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&gt; 1,如何将任务分配给准备好的和分配的(在循环中)线程?

我想(我不确定)是否有线程池和某种循环策略将任务分配给线程,但它可以在运行时完全动态完成,或者在开始时通过创建过滤完成一次/映射到结构。

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

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

2 个答案:

答案 0 :(得分:2)

  

如果有例如num.stream.threads&gt; 1,如何分配任务   准备好并分配(在循环中)线程?

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

答案 1 :(得分:2)

在内部,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的所有内部细节,建议您不要弄乱分组的分区 - 您可以轻松破解内容!

关于线程:任务限制线程数。对于我们的示例,这意味着您可以拥有最多4个线程(如果您有更多,那些线程将是空闲的,因为没有任务留给线程分配)。你如何“分发”这些线程取决于你。您可以拥有4个单线程应用程序实例的4个单线程应用程序实例,其中包含4个线程(或其间的任何内容)。

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