Flink,使用多个Kafka源时如何正确设置并行度?

gfy*_*ytd 7 apache-flink flink-streaming

我仍然无法清楚地了解并行性,假设我们有一个有足够插槽的 flink 集群。在我们的 flink 作业中,我们使用来自 3 个不同 kafka 集群的 3 个 kafka 主题,每个主题有 10 个分区。

如果我们想尽快消费消息。并行性应该是什么?

如果我们设置parallelism为10,那么就会使用10个slot,按照我的理解就是10个线程对吧?如果这 10 个线程“连接”到 topic_1,则没有线程读取 topic_2 和 topic_3。

如果我们将并行度设置为 30,则有 30 个线程,但是这 30 个线程是否足够智能,其中 10 个转到 topic_1,其中 10 个转到 topic_2,其余 10 个转到 topic_3?

Soh*_*ani 11

卡夫卡消费者组

每个 Kafka 消费者都属于一个消费者组,即可以将其视为一组消费者的逻辑容器/命名空间。一个消费者组可以接收来自一个或多个主题的消息。消费者组中的实例可以从每个主题内的零个、一个或多个分区接收消息(取决于分区和消费者实例的数量)

在此处输入图片说明

Kafka 分区如何分配给 Flink 工作人员?

在 Kafka 中,来自同一消费者组的每个消费者都会被分配一个或多个分区。请注意,两个消费者不可能从同一个分区消费。Flink 消费者的数量取决于 Flink 并行度,这意味着每个 Flink 任务(我们粗略地认为每个 Flink 任务 = Flink 插槽 = Flink 并行度 = 可用 CPU 核)可以作为一个消费者组中的一个单独的消费者。此外,您应该注意到主题只是对分区和数据进行分组的抽象,内部仅分区根据以下模式分配给 Flink 的并行任务实例。

有三种可能的情况:

1.kafka分区==flink并行

这种情况是理想的,因为每个消费者负责一个分区。如果您的消息在分区之间是平衡的,那么工作将均匀分布在 Flink 操作员之间

2.kafka分区<flink并行

当 Flink 任务多于 Kafka 分区时,部分 Flink 消费者将只是空闲,不读取任何数据:

在此处输入图片说明

在这种情况下,如果您的并行度高于分区数(因为您想在未来的运算符中使用它),您可以.rebalance()在 Kafka 源之后执行。这确保了 Kafka 源之后的所有操作符都能获得均匀的负载,代价是必须重新分配数据(因此存在反/序列化 + 网络开销)。

3. kafka 分区 > flink 并行

当 Kafka 分区多于 Flink 任务时,Flink 消费者实例会同时订阅多个分区:

在此处输入图片说明

在所有情况下,Flink 都会以最佳方式将任务分配给分区。

在您的情况下,您可以使用 Flink Kafka 连接器创建 Kafka Consumer 组并为其分配一个或多个主题(例如使用 Regex)。所以如果Kafka有3个topic,每个topic有10个partition,给Flink Job Manager分配30个slot(core),就可以达到理想的情况,即每个consumer(Flink slot)消费一个Kafka partition。

参考: 1 , 2 , 3