【问题标题】:Understanding kafka streams partition assignor了解 kafka 流分区分配器
【发布时间】:2019-04-16 14:45:31
【问题描述】:

我有两个主题,一个有 3 个分区,一个有 48 个分区。

最初我使用默认分配器,但是当消费者(kubernetes 中的 pod)崩溃时我遇到了一些问题。

发生的情况是,当 pod 再次出现时,它重新分配了 3 个分区的主题的分区和 48 的主题的 0。

没有崩溃的两个 pod 分别从 48 个分区的主题中分配了 16 个和 32 个分区。

我已经通过使用循环分区分配器解决了这个问题,但现在我对分区的分配方式没有信心,因为我使用的是 kstream-kstream 连接,为此我们需要保证分配了消费者到所有消费者的同一个分区,例如C1:(t1:p0, t2:p0) C2(t1:p1, t2:p1) 等等。

我想到的一件事是,我可以对传入的事件重新设置密钥,以便它们重新分区,然后我可以保证这一点?

或者我不明白默认分区是如何工作的……我很困惑

【问题讨论】:

  • 实际上,Kafka Streams 不允许使用自定义分区分配器。可能您的自定义分区分配器被忽略了。此外,根据 Kafka Streams docsjoin 的输入主题(左侧和右侧)必须具有相同的分区数。
  • 好的,所以我想合并流,然后做一个 stream.through(newTopic) 只是为了将数据流合并到一个具有 3 个分区的主题,然后将它们过滤到两个流和加入吗?你怎么看这个想法?我正在考虑的另一个解决方案是创建一个微服务,它只将消息转发到一个主题,然后将它们过滤到两个新的 kstream 并进行连接.. 有更好的想法吗?还有分区分配器,当涉及到 kstreams 时,没有办法改变它?
  • 看来你可以在这里找到答案:stackoverflow.com/questions/18202986/…
  • @dmvkl:您链接到的线程涵盖了如何自定义生产者端的分区器以及消费者端的默认分区分配器如何工作。但是,这里的问题是关于自定义分区分配器。

标签: java spring-boot apache-kafka apache-kafka-streams


【解决方案1】:

Kafka Streams 不允许使用自定义分区分配器。如果您自己设置一个,它将被StreamsPartitionAssignor [1] 覆盖。这是为了确保 - 如果可能的话 - 在重新平衡期间将分区重新分配给相同的消费者(也称为粘性)。粘性对于 Kafka Streams 能够在消费者端尽可能重用状态存储非常重要。如果一个分区没有重新分配给同一个消费者,那么这个消费者中使用的状态存储需要在重新平衡后从头开始重新创建。

[1]https://github.com/apache/kafka/blob/9bd0d6aa93b901be97adb53f290b262c7cf1f175/streams/src/main/java/org/apache/kafka/streams/StreamsConfig.java#L989

【讨论】:

  • 再次感谢。更改应用程序内的键时,应用程序和 kafka 将如何表现。到目前为止,我所看到的是正在进行一些重新分区。它在我不想要的负载下大量记录它。但这是否意味着坏消息?
  • 记录在键更改操作和基于键的操作之间重新分区。例如,map 输出一个新密钥,后跟一个 groupByKey。见groupByKeyjavadocs
猜你喜欢
  • 1970-01-01
  • 2016-10-27
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
  • 2018-10-08
相关资源
最近更新 更多