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

14

我仍然无法清晰地理解并行性,假设我们有一个拥有足够 slot 的 flink 集群。在我们的 flink 作业中,我们从三个不同的 kafka 集群消费了 3 个 kafka 主题,每个主题有 10 个分区。

如果我们想尽快消费消息,那么并行度应该设置为多少?

如果我们将并行度设置为 10,则使用 10 个 slot,这意味着根据我的理解,会使用 10 个线程,对吗?如果这 10 个线程“连接”到 topic_1,那么就没有线程读取 topic_2 和 topic_3。

如果我们将并行度设置为 30,则会有 30 个线程,但是这 30 个线程会聪明到其中 10 个进入 topic_1,另外 10 个进入 topic_2,并且剩下的 10 个进入 topic_3 吗?

1个回答

20

Kafka消费者组

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

enter image description here

「Kafka分区是如何分配给Flink工作器的?」
在Kafka中,同一消费者组中的每个消费者会被分配一个或多个分区。请注意,两个消费者不可能从同一分区消费数据。Flink消费者的数量取决于Flink并行度,也就是说,每个Flink任务(我们大致认为每个Flink任务=Flink插槽=Flink并行度=可用CPU核心)都可以作为消费者组中的单独消费者。值得注意的是,主题只是用于分组分区和数据的抽象表示,在内部只有分区根据以下方式分配给Flink的并行任务实例。
「有三种可能情况:」
1. kafka分区数==flink并行度
这种情况非常理想,因为每个消费者都处理一个分区。如果您的消息在分区之间平衡,则工作将均匀地分布在Flink操作符之间。
2. kafka分区数
当Flink任务数大于Kafka分区数时,一些Flink消费者将闲置,不读取任何数据:

enter image description here

在这种情况下,如果您的并行度高于分区数(因为您想在未来的操作中使用它),您可以在Kafka源后执行.rebalance()。这样可以确保Kafka源后的所有操作符都获得平均负载,但代价是需要重新分配数据(因此存在序列化/反序列化+网络开销)。
当Kafka分区数大于Flink任务数时,Flink消费者实例将同时订阅多个分区。

enter image description here

在所有情况下,Flink都会将任务最优地分配给分区。
在您的情况下,您可以使用Flink Kafka连接器创建Kafka Consumer组,并将一个或多个主题分配给它(例如使用Regex)。因此,如果Kafka有三个主题,每个主题包含10个分区,将30个槽(核心)分配给Flink作业管理器,您可以实现理想情况,这意味着每个消费者(Flink槽)将消耗一个Kafka分区。
参考资料: 1, 2, 3

嗨,目前我正在为所有三个主题使用一个单一的group.id,这会有影响吗? - gfytd
1
谢谢。那么在我的情况下,将并行度设置为30,flink将会“分配”一个分区到一个槽中,对吗?这听起来对我来说非常聪明 :) - gfytd
是的,只需将并行度设置为分区数即可! - Soheil Pourbafrani
你是在指 StreamExecutionEnvironment.setParalellism 吗?因为注释中指出这个值仅适用于 Datastream 运算符,没有提到源。 (至少对于 flink 1.9) - Manos Ntoulias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接