简体   繁体   English

在 Kafka Streams 中,如何使用多个主题和分区并行化复杂操作(或子拓扑)?

[英]In Kafka Streams, how do you parallelize complex operations (or sub-topologies) using multiple topics and partitions?

I am currently trying to understand how Kafka Streams achieves parallelism.我目前正在尝试了解 Kafka Streams 如何实现并行性。 My main concern boils down to three questions:我主要关心的问题归结为三个问题:

  1. Can multiple sub-topologies read from the same partition?多个子拓扑可以从同一个分区读取吗?
  2. How can you parallelise a complex operation (making up a sub-topology) that uses the processor API and requires reading the entire topic?如何并行使用处理器 API 并需要阅读整个主题的复杂操作(构成子拓扑)?
  3. Can multiple sub-topologies read from the same topic (such that independent and expensive operations on the same topic can be run in different sub-topologies)?多个子拓扑可以从同一个主题读取(这样对同一个主题的独立且昂贵的操作可以在不同的子拓扑中运行)吗?

As the developer, we don't have direct control about how topologies are divided into sub-topologies.作为开发人员,我们无法直接控制拓扑如何划分为子拓扑。 Kafka Streams divides the Topology into multiple sub-topologies using Topics as a "bridge" where possible. Kafka Streams 在可能的情况下使用主题作为“桥梁”将拓扑划分为多个子拓扑。 Additionally, multiple stream tasks are created that each read a subset of data from the input topic, divided by partition.此外,还创建了多个 stream 任务,每个任务从输入主题中读取数据的一个子集,并按分区划分。 The documentation reads: 文件内容如下:

Slightly simplified, the maximum parallelism at which your application may run is bounded by the maximum number of stream tasks, which itself is determined by maximum number of partitions of the input topic(s) the application is reading from.稍微简化一下,您的应用程序可以运行的最大并行度受 stream 任务的最大数量限制,而任务本身由应用程序正在读取的输入主题的最大分区数决定。


Assume there was a sub-topology that reads multiple input topics whose number of partitions are not identical.假设有一个子拓扑读取多个分区数量不相同的输入主题。 If the above excerpt of the documentation is to be believed, then one or more partitions of the topic that has less partitions would need to be assigned to multiple stream tasks (if both topics need to be read for the logic to work).如果上述文档摘录可信,那么需要将分区较少的主题的一个或多个分区分配给多个 stream 任务(如果需要阅读两个主题以使逻辑起作用)。 However, this should not be possible, because, as I understand it, multiple instances of the streams application (each sharing the same application id) act as one Consumer group, where each partition is only assigned once .但是,这应该是不可能的,因为据我了解,流应用程序的多个实例(每个实例共享相同的应用程序 ID)充当一个消费者组,其中每个分区只分配一次 In such a case, the number of tasks being created for a sub-topology should actually be limited by the minimum number of partitions of its input topics, ie a single partition is only assigned to one Task.在这种情况下,为子拓扑创建的任务数实际上应受其输入主题的最小分区数限制,即单个分区仅分配给一个任务。

I am not sure if the initial problem, ie a non-co-partitioned sub-topology would actually occur.我不确定最初的问题,即非共同分区的子拓扑是否真的会发生。 If there is an operation that requires to read both input topics, the data would probably need to be co-partitioned (like in Joins).如果有一个操作需要读取两个输入主题,则数据可能需要共同分区(如在联接中)。


Say there was an expensive operation between two topics (possibly built from multiple custom processors) that requires the data of one topic to always be available in its entirety.假设两个主题(可能由多个自定义处理器构建)之间存在一项昂贵的操作,该操作要求一个主题的数据始终完整可用。 You would want to parallelise this operation into multiple tasks.您可能希望将此操作并行化为多个任务。

If the topic had just one partition, and a partition could be read multiple times, this would not be a problem.如果主题只有一个分区,并且一个分区可以被多次读取,这将不是问题。 However, as discussed earlier, I don't believe this to work.但是,如前所述,我认为这行不通。

Then there are GlobalKTables.然后是 GlobalKTables。 However, there is no way to use GlobalKTables with custom processors (toStream is not available).但是,无法将 GlobalKTables 与自定义处理器一起使用(toStream 不可用)。

Another idea would be to broadcast the data into multiple partitions, essentially duplicating it by the partition count.另一个想法是将数据广播到多个分区,本质上是按分区计数复制数据。 This way, multiple stream tasks could be created for the topology to read the same data.这样,可以为拓扑创建多个 stream 任务来读取相同的数据。 To do this, a custom partitioner could be specified in the Produced -Instance given to KStream#to .为此,可以在提供给KStream#toProduced -Instance 中指定自定义分区程序。 If this data duplication can be accepted, this seems to be the only way to achieve what I have in mind.如果可以接受这种数据重复,这似乎是实现我的想法的唯一方法。


Regarding question number three, because the Streams application is one Consumer group, I would also expect this to not be possible.关于第三个问题,因为 Streams 应用程序是一个消费者组,所以我也希望这是不可能的。 With my current understanding, this would require to write the data into multiple identical topics (again essentially duplicating the data), such that independent sub-topologies can be created.根据我目前的理解,这将需要将数据写入多个相同的主题(同样本质上是复制数据),以便可以创建独立的子拓扑。 An alternative would be to run separate streaming applications (such that a different consumer group is used).另一种方法是运行单独的流式应用程序(以便使用不同的消费者组)。

Without seeing your topology definition, this is a somewhat vague question.没有看到您的拓扑定义,这是一个有点模糊的问题。 You can have repartition and changelog topics.您可以拥有重新分区和更改日志主题。 These are duplicated data from the original input topic.这些来自原始输入主题的重复数据。

But stateless operators like map, filter, etc. pass data through from the same (assigned) partitions for each thread.但是像 map、filter 等无状态运算符从每个线程的相同(分配的)分区传递数据。

A "sub topology" is still part of only one application.id , thus one consumer group, so no, it cannot read the same topic partitions more than once. “子拓扑”仍然只是一个application.id的一部分,因此是一个消费者组,所以不,它不能多次读取相同的主题分区。 For that, you'd need independent streams/tables via branching operations within the whole topology, for example, filtering numbers by even and odd only consumes the topic once;为此,您需要通过整个拓扑中的分支操作来实现独立的流/表,例如,按偶数和奇数过滤数字只会消耗主题一次; you don't need to "broadcast" records to all partitions, and I'm not sure that's even possible out of the box ( to sends one-to-one, and Produced defines serialization, not multiple partitions).您不需要将记录“广播”到所有分区,而且我不确定开箱即用(一对一toProduced定义序列化,而不是多个分区)。 If you need to cross reference different operators, then you can use join / statestores / KTables.如果你需要交叉引用不同的运算符,那么你可以使用 join/statestores/KTables。


None of this is really related to parallelism.这些都与并行性无关。 You have num.stream.threads , or you can run multiple instances of the same JVM process to scale.您有num.stream.threads ,或者您可以运行同一 JVM 进程的多个实例以进行扩展。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用多个子拓扑优化Kafka Streams应用程序 - Optimizing a Kafka Streams Application with Multiple Sub-Topologies 无法在 Kafka Stream App 的子拓扑之间共享状态存储中的数据 - Not able to share data in state store among sub-topologies of a Kafka Stream App Kafka Streams 在监听具有多个分区的主题时如何确保处理所有相关数据? - How to ensure for Kafka Streams when listening to topics with multiple partitions that all related data is processed? 如何在 Kafka 中对主题/分区进行分类? - How to classifier topics/partitions in Kafka? 如何确保多个 Kafka 拓扑具有所有主题的相同分区分配? - How to make sure multiple Kafka topologies have same partition assignment of all topics? kafka - 多个主题与多个分区 - kafka - multiple topics vs multiple partitions 使用 Kafka Streams 从多个主题中累积事件 - Accumulate Events from Multiple Topics using Kafka Streams 多个 Kafka 分区到 Akka Streams - Multiple Kafka Partitions to Akka Streams Kafka Streams:使用 Spring Cloud Stream 为每组主题定义多个 Kafka Streams - Kafka Streams: Define multiple Kafka Streams using Spring Cloud Stream for each set of topics 您如何从 Spring-Apache-Kafka-Streams 中的 Kafka 输入主题中读取数据,并对特定的 output 主题进行不同的分析? - How do you read from a Kafka input topic in Spring-Apache-Kafka-Streams and produce different analytics on specific output topics?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM