我在代码中做的更少这样的设置:
// 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=2
,no. partitions=4
,no. topics=2
(huge_topic和slim_topic)
我的问题循环在应用程序启动时完成一次。如果在循环中我定义了2个主题,并且我从一个主题知道了重量级的加权(huge_topic),另一个是轻量级的消息(slim_topic)。
来自num.stream.threads的两个线程是否可能只忙于来自huge_topic的任务?来自slimm_topic的消息将不得不等待处理?
答案 0 :(得分:2)
如果有例如num.stream.threads&gt; 1,如何分配任务 准备好并分配(在循环中)线程?
使用分区分组器为线程分配任务。你可以阅读它here。 AFAIK是在重新平衡后调用的,因此它不是一个非常动态的过程。也就是说,我认为没有饥饿的选择。
答案 1 :(得分:2)
在内部,Kafka Streams基于分区创建任务。继续你的循环示例并假设你有3个输入主题A,B,C分别有2,4和3分区。为此,您将获得4个任务(即所有主题的最大分区数),并将以下分区用于任务分配:
分区按“编号”分组并分配给相应的任务。这是在运行时确定的(即,在您调用KafakStreams#start()
之后),因为在此之前,每个主题的分区数量是未知的。
如果您不了解Kafka Streams的所有内部细节,建议您不要弄乱分组的分区 - 您可以轻松破解内容!
关于线程:任务限制线程数。对于我们的示例,这意味着您可以拥有最多4个线程(如果您有更多,那些线程将是空闲的,因为没有任务留给线程分配)。你如何“分发”这些线程取决于你。您可以拥有4个单线程应用程序实例的4个单线程应用程序实例,其中包含4个线程(或其间的任何内容)。
如果任务少于线程,则任务将根据任务数量以负载平衡的方式分配(假设所有任务具有相同的负载)。