如何在apache kafka连接器中准确实现一次语义

时间:2019-11-20 18:39:51

标签: apache-flink flink-streaming

我正在使用flink版本1.8.0。我的应用程序从kafka中读取数据-> transform->发布到Kafka。为了避免在重新启动过程中出现任何重复,我想使用具有恰好一次语义的kafka生产者,请在此处阅读:

https://ci.apache.org/projects/flink/flink-docs-release-1.8/dev/connectors/kafka.html#kafka-011-and-newer

我的kafka版本是1.1。

        return new FlinkKafkaProducer<String>( topic,  new KeyedSerializationSchema<String>() {


            public byte[] serializeKey(String element) {
                // TODO Auto-generated method stub
                return element.getBytes();
            }


            public byte[] serializeValue(String element) {
                // TODO Auto-generated method stub
                return element.getBytes();
            }


            public String getTargetTopic(String element) {
                // TODO Auto-generated method stub
                return topic;
            }
        },prop, opt, FlinkKafkaProducer.Semantic.EXACTLY_ONCE, 1);

检查点代码:

    CheckpointConfig checkpointConfig = env.getCheckpointConfig();
    checkpointConfig.setCheckpointTimeout(15 * 1000 );
    checkpointConfig.enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
    env.enableCheckpointing(5000 );

如果我在kafka生产者中仅添加一次语义,则我的flink消费者不会读取任何新数据。

任何人都可以与语义一次共享任何示例代码/应用程序吗?

请在此处找到完整的代码:

https://github.com/sris2/sample_flink_exactly_once

谢谢

1 个答案:

答案 0 :(得分:1)

  

任何人都可以与语义一次共享任何示例代码/应用程序吗?

end-to-end test in flink中隐藏了一个示例。由于它使用了一些便利功能,因此如果不检查整个存储库,可能很难遵循。

  

如果我在kafka生产者中仅添加了一次语义,那我的flink消费者   没有读取任何新数据。   [...]   请在此处找到完整的代码:

     

https://github.com/sris2/sample_flink_exactly_once

我检查了您的代码并发现了问题(必须修复整个设置/代码以使其实际运行)。接收器实际上无法正确配置事务。按照Flink Kafka connector documentation中所述,您需要在您的Kafka经纪人中调整transaction.timeout.ms最多1小时,或者在您的应用程序中调整15分钟以下:

    prop.setProperty("transaction.timeout.ms", "900000");

相应的摘录是:

  

默认情况下,Kafka经纪人的transaction.max.timeout.ms设置为15分钟。此属性不允许为生产者设置大于其值的交易超时。默认情况下,FlinkKafkaProducer011将生产者配置中的transaction.timeout.ms属性设置为1小时,因此在使用Semantic.EXACTLY_ONCE模式之前,应增加transaction.max.timeout.ms。