FlinkKafkaConsumer09一次又一次地读取一些消息

时间:2016-07-15 00:54:05

标签: java apache-kafka apache-flink flink-streaming

我写了一个简单的程序来从Kafka读取数据并在flink中打印。以下是代码。

public static void main(String[] args) throws Exception {

    Options flinkPipelineOptions = PipelineOptionsFactory.create().as(Options.class);

    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    Class<?> unmodColl = Class.forName("java.util.Collections$UnmodifiableCollection");
    env.getConfig().addDefaultKryoSerializer(unmodColl, UnmodifiableCollectionsSerializer.class);
    env.enableCheckpointing(1000, CheckpointingMode.EXACTLY_ONCE);

    flinkPipelineOptions.setJobName("MyFlinkTest");
    flinkPipelineOptions.setStreaming(true);
    flinkPipelineOptions.setCheckpointingInterval(1000L);
    flinkPipelineOptions.setNumberOfExecutionRetries(5);
    flinkPipelineOptions.setExecutionRetryDelay(3000L);

    Properties p = new Properties();
    p.setProperty("zookeeper.connect", "localhost:2181");
    p.setProperty("bootstrap.servers", "localhost:9092");
    p.setProperty("group.id", "test");

    FlinkKafkaConsumer09<Notification> kafkaConsumer = new FlinkKafkaConsumer09<>("testFlink",new ProtoDeserializer(),p);

    DataStream<Notification> input = env.addSource(kafkaConsumer);

    input.rebalance().map(new MapFunction<Notification, String>() {
        @Override
        public String map(Notification value) throws Exception {
            return "Kafka and Flink says: " + value.toString();
        }

    }).print();

    env.execute();
}

我需要flink在kafka中处理我的数据一次,我对如何完成它几乎没有疑问。

  • FlinkKafkaConsumer09何时将处理后的偏移提交给kafka?
  • 假设我的主题有10条消息,消费者处理所有10条消息。当我停止作业并再次启动它时,它开始处理先前读取的消息集中的随机消息。我需要确保我的消息都不会被处理两次。

请指教。感谢所有的帮助。谢谢。

1 个答案:

答案 0 :(得分:0)

此页面介绍了fault tolerance guarantees of the Flink Kafka connector

您可以使用Flink's savepoints to re-start a job in an exactly-once (state preserving) manner

您再次看到这些消息的原因是因为Flink向Kafka经纪人/ Zookeeper提交的抵消与Flink的注册状态不一致。 在Flink中恢复/失败后,您将始终看到多次处理消息,即使启用了一次语义也是如此。 exactly-once guarantees in Flink是关于注册状态的,而不是发送给运营商的记录。

稍微偏离主题:这些行是什么?它们不会在任何地方传递给Flink。

Options flinkPipelineOptions = PipelineOptionsFactory.create().as(Options.class);
flinkPipelineOptions.setJobName("MyFlinkTest");
flinkPipelineOptions.setStreaming(true);
flinkPipelineOptions.setCheckpointingInterval(1000L);
flinkPipelineOptions.setNumberOfExecutionRetries(5);
flinkPipelineOptions.setExecutionRetryDelay(3000L);