Flink Kafka-Flink作业未将消息发送到其他分区

时间:2018-08-29 09:59:53

标签: apache-kafka apache-flink kafka-producer-api

我具有以下配置:

  1. 一个带有2个分区的kafka主题
  2. 一个动物园管理员实例
  3. 一个kafka实例
  4. 两个具有相同组ID的消费者

Flink作业摘要:

speStream.addSink(new FlinkKafkaProducer011(kafkaTopicName,new 
SimpleStringSchema(), props));

场景1:

我在eclipse上写了一个flink作业(生产者),该作业是从文件夹中读取文件并将msg放在kafka主题上。

因此,当我使用Eclipse运行此代码时,效果很好。

例如::如果我放置一个包含100条记录的文件,则flink将几个msg发送到分区1,将几个msg发送到分区2,因此这两个使用者都将得到几个msg。

方案2: 当我创建上述代码的jar并在flink服务器上运行时,flink将所有msg发送到单个分区,因此只有一个使用者可以获取所有msg。

我想要使用在场景2中创建的jar的场景1。

2 个答案:

答案 0 :(得分:1)

如果您未提供FlinkKafkaPartitioner或未明确表示使用Kafka的密钥,则将使用FlinkFixedPartitioner,这意味着来自一个任务的所有事件都将在同一分区中结束。

要使用Kafka的分区程序,请使用以下ctor:

speStream.addSink(new FlinkKafkaProducer011(kafkaTopicName,new SimpleStringSchema(), props), Optional.empty());

从IDE和eclipse运行之间的差异可能是由于Flink中并行性或分区设置不同所致。

答案 1 :(得分:1)

对于Flink-Kafka生产者,将“ null”添加为最后一个参数。

speStream.addSink(new FlinkKafkaProducer011(
    kafkaTopicName,
    new SimpleStringSchema(),
    props,
    (FlinkKafkaPartitioner) null)
);

对此的简短解释是,这将使Flink无法使用默认分区程序FlinkFixedPartitioner。默认情况下将其关闭,这将允许Kafka在认为合适的情况下在其分区之间分配数据。如果未将其关闭,则用于使用FlinkKafkaProducer的接收器的每个并行度/任务插槽将仅向每个并行度/任务插槽写入一个分区。