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=4
,no. 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 个单线程应用程序实例。
如果您的任务比线程少,任务将根据任务数量以负载平衡的方式分配(假定所有任务具有相同的负载)。
我在代码中做了这样的设置:
// 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=4
,no. 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 个单线程应用程序实例。
如果您的任务比线程少,任务将根据任务数量以负载平衡的方式分配(假定所有任务具有相同的负载)。