如何扩展 Kafka Stream 应用程序

pos*_*ver 1 apache-kafka apache-kafka-streams

我对 kafka 文档中关于这个主题的措辞有点困惑,所以我想在这里问我是否正确地解释了这些内容?

因此,如果我正确理解这种扩展 Kafka Stream 应用程序的唯一方法是启动应用程序的新实例(或增加 application 中的流线程数量),这将确保 ConsumerGroup('application. id'),这样我就可以将流应用程序扩展到主题的分区数量(如果我的流拓扑连接到多个主题,实际上会发生什么,假设 TopicA 有 5 个分区,topicB 有 3 个分区,我加入了 TopicA 和 TopicB 的流,我猜在这种情况下我可以扩展到 3 个实例/线程)。

现在假设我有一个包含 5 个分区的 topicA,并且启动了应用程序的 3 个实例,如果我在拓扑中配置了 KTable,则每个 KTable 将包含来自特定分区的信息,并且我必须找出我的哪个实例(分区)上的元数据关键是,那么当我启动第四个实例时会发生什么,假设实例3上的KTable的键/值现在可以转到实例4上的KTable,不是吗?一方面问题是这样的重新平衡需要多长时间(我认为这取决于主题大小,所以假设需要 1 分钟,我正在查询 KTable 的应用程序在此操作期间会没有响应吗?)

附带问题是,此机制对于“streamBuilder.table(..)”和“streambuilder.groupByKey(..).reduce(..)”的工作原理是否完全相同?

最后一个问题,同样是一个具有 5 个分区的主题,但我没有启动 3 个应用程序实例,而是启动了一个具有 3 个流线程的实例 (num.stream.threads = 3),我会再次拥有 3 个 KTable 代表 5 个分区吗?如果我将线程大小从 3 更改为 4,其行为与增加实例数完全相同。

感谢您的回答..

Nis*_*yal 9

假设 TopicA 有 5 个分区,topicB 有 3 个分区,我加入了 TopicA 和 TopicB 的流,我猜在这种情况下我可以扩展到 3 个实例/线程)。

首先,为了连接两个主题,它们应该具有相同数量的分区。这是加入的关键要求。如果主题 A 的分区数为 5,主题 B 的分区数为 3,则它永远不会执行 join。(https://docs.confluence.io/current/streams/developer-guide/dsl-api.html#join-co-partitioning-requirements

当我启动第四个实例时会发生什么,

是的,Kafka 流将根据分区数量重新平衡实例之间的工作负载。它将重新分配分区及其任务,包括本地状态存储。时间取决于主题的大小。如果有最终用户查询 ktable,您应该更喜欢从所有实例收集元数据并执行查找。

此机制对于“streamBuilder.table(..)”和“streambuilder.groupByKey(..).reduce(..)”的工作原理是否完全相同?

是的,每当使用任何转换创建 ktable 时都会遵循相同的机制。

又是一个具有 5 个分区的主题,但我没有启动 3 个应用程序实例,而是启动了一个具有 3 个流线程 (num.stream.threads = 3) 的实例,我将再次拥有 3 个 KTable 代表 5 个分区,它的行为是否与如果我将线程大小从 3 更改为 4,则会增加实例数。

默认情况下,Kafka Streams 会将拓扑分成 5 个任务(= 分区数)。如果设置num.stream.threads为 3,这些任务将分布在指定的线程上。因此,线程 1可以运行 2 个任务,线程 2可以运行接下来的 2 个任务,线程 3可以运行 1 个任务。
KTable状态将被划分为5个分片(=分区数),一个分片将映射到一个任务。因此,每个任务都会创建一个不包括其自身的本地存储。这些Local store包含相应分片的数据。尽管线程数量有多少,您将获得本地存储等于分区数量。

例子 :

添加一个实例后