• FLINK实例(8):CONNECTORS(7)FlinkKafkaConsumer官网文档翻译以及Flink消费Kafka数据时指定offset的五种方式


    以下内容翻译自Apache Flink Kafka Connector官网(内容顺序稍作修改)

    Flink为Kafka topic读取和写入数据提供了特殊的Kafka连接器。Flink Kafka消费者与Flink的检查点机制集成可以保证下游的exactly-once语义。为了实现这一点,Flink并不完全依赖Kafka自身维护的消费者组offset,而是在Flink内部管理这些offset。

    从Flink 1.7开始,Flink提供了一个新的通用的Kafka连接器,它不再绑定特定版本的Kafka。相反,它绑定的是Flink发行时最新版本的Kafka。
    如果您的Kafka版本是1.0.0或更新版本,您应该使用这个Kafka连接器。如果使用Kafka的旧版本(0.11、0.10、0.9或0.8),则应该使用与kafka版本对应的连接器。

    导入Maven依赖:

    通用kafka(1.0.0版本及以后):

    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-connector-kafka_2.11</artifactId>
      <version>1.9.0</version>
    </dependency>

    kafka版本(0.11版本及以前):

    <dependency>
      <groupId>org.apache.flink</groupId>
    <!--kafka是哪个版本,这里就写版本号,如0.11版本-->
      <artifactId>flink-connector-kafka-0.11_2.11</artifactId>
      <version>1.9.0</version>
    </dependency>

    Kafka Consumer

    构造器有以下参数:

    • topic名或者多个topic的集合;
    • 从kafka接收数据的序列化/反序列化schema;
    • kafka消费者的配置信息

    例如:

    Properties properties = new Properties();
    properties.setProperty("bootstrap.servers", "localhost:9092");
    // only required for Kafka 0.8
    properties.setProperty("zookeeper.connect", "localhost:2181");
    properties.setProperty("group.id", "test");
    DataStream<String> stream = env
      .addSource(new FlinkKafkaConsumer08<>("topic", new SimpleStringSchema(), >properties));

    The DeserializationSchema

      Flink Kafka Consumer如何将Kafka中的二进制数据转换为Java / Scala对象。这就需要指定序列化和反序列化方式。每个Kafka消息都会调用T deserialize(byte[] message)方法。
    后边的太难了,自己去官网看吧:https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/connectors/kafka.html#the-deserializationschema

    Kafka Consumers 从指定位置开始消费

    final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    
    env.enableCheckpointing(5000);
    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
    env.setParallelism(1);
    
    Properties props = new Properties();
    props.setProperty("bootstrap.servers",KAFKA_BROKER);
    props.setProperty("zookeeper.connect", ZK_HOST);
    props.setProperty("group.id",GROUP_ID);
    props.setProperty("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    props.setProperty("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    
    FlinkKafkaConsumer011<String> consumer = new FlinkKafkaConsumer011<>(TOPIC, new SimpleStringSchema(), props);
    
    /**
    * Map<KafkaTopicPartition, Long> Long参数指定的offset位置
    * KafkaTopicPartition构造函数有两个参数,第一个为topic名字,第二个为分区数
    * 获取offset信息,可以用过Kafka自带的kafka-consumer-groups.sh脚本获取
    */
    Map<KafkaTopicPartition, Long> offsets = new HashedMap();
    offsets.put(new KafkaTopicPartition("maxwell_new", 0), 11111111l);
    offsets.put(new KafkaTopicPartition("maxwell_new", 1), 222222l);
    offsets.put(new KafkaTopicPartition("maxwell_new", 2), 33333333l);
    
    /**
    * Flink从topic中最初的数据开始消费
    */
    consumer.setStartFromEarliest();
    
    /**
    * Flink从topic中指定的时间点开始消费,指定时间点之前的数据忽略
    */
    consumer.setStartFromTimestamp(1559801580000l);
    
    /**
    * Flink从topic中指定的offset开始,这个比较复杂,需要手动指定offset
    */
    consumer.setStartFromSpecificOffsets(offsets);
    
    /**
    * Flink从topic中最新的数据开始消费
    */
    consumer.setStartFromLatest();
    
    /**
    * Flink从topic中指定的group上次消费的位置开始消费,所以必须配置group.id参数
    * 这也是默认的方式
    */
    consumer.setStartFromGroupOffsets();

    说明:

    • setStartFromGroupOffsets()<默认>:从Kafka Broker(或Kafka 0.8之前的Zookeeper)中的消费者组(在消费者属性中设置的group.id)提交的偏移量开始按分区读取。如果找不到分区的偏移量,则使用auto.offset.reset属性中设置的值。
    • setStartFromEarliest() / setStartFromLatest():最最早或者最近的记录开始消费,在这种模式下,kafka中已经提交的offsets将会被忽略,并且也不会被用作消费的起始位置。
    • setStartFromTimestamp(long):从指定的时间戳开始,对于每个分区,就是时间戳从大于等于指定的时间戳的消息作为起始位置,如果分区的最新记录比指定的时间戳更早,则只从最新记录开始读取分区,在这种模式下,kafka中已经提交的offsets将会被忽略,并且也不会被用作消费的起始位置。

    Kafka消费者容错机制

    启用Flink的checkpoint机制后,Flink Kafka Consumer在消费kafka消息的同时,会周期的并保持一致性的将offset写入checkpoint中。如果作业失败,Flink会将程序恢复到最新的checkpoint的状态,并从存储在checkpoint中的偏移量开始重新消费Kafka中的消息。

    final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    env.enableCheckpointing(5000); // checkpoint every 5000 msecs

    注意,只有在有足够的slots可用来重新启动时,Flink才能重新启动。
    如果没有启用checkpoint机制,Kafka使用者将定期向Zookeeper提交偏移量。

    Kafka Consumer offset提交配置

      Flink Kafka Consumer可以将偏移量提交到Kafka broker(或0.8中的Zookeeper)。注意,Flink Kafka Consumer并不依赖提交的偏移量来保证容错。提交的偏移量只是用于方便查看Consumer消费的进度。
    提交偏移量有多种不同的方式,与是否为Job启用了checkpoint机制有关。

    • 禁用checkpoint:Flink Kafka Consumer依赖于Kafka 客户端内部的自动定期提交偏移量功能。因此,要禁用或启用提交偏移量,只需将属性配置中enable.auto.commit(或Kafka 0.8的auto.commit.enable) / auto.commit.interval.ms设置适当的值即可。
    • 启用checkpoint:当执行checkpoint时,Flink Kafka Consumer将offset提交并存储在checkpoint中。这可以确保Kafka broker中提交的偏移量与检查点状态中的偏移量一致。用户也可以通过Consumer的setCommitOffsetsOnCheckpoints(boolean)方法来禁用或启用偏移提交(默认情况下为true)。注意,这种场景下在Kafka Consumer属性中定义的自动提交offset的配置则会完全被忽略。

    Flink消费Kafka数据时指定offset的五种方式

    下面是Flink读取Kafka数据的代码,其中就有五种读取offset的方式,并配置相应的介绍
    final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    
    env.enableCheckpointing(5000);
    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
    env.setParallelism(1);
    
    Properties props = new Properties();
    props.setProperty("bootstrap.servers",KAFKA_BROKER);
    props.setProperty("zookeeper.connect", ZK_HOST);
    props.setProperty("group.id",GROUP_ID);
    props.setProperty("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    props.setProperty("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    
    FlinkKafkaConsumer011<String> consumer = new FlinkKafkaConsumer011<>(TOPIC, new SimpleStringSchema(), props);
    
    /**
    * Map<KafkaTopicPartition, Long> Long参数指定的offset位置
    * KafkaTopicPartition构造函数有两个参数,第一个为topic名字,第二个为分区数
    * 获取offset信息,可以用过Kafka自带的kafka-consumer-groups.sh脚本获取
    */
    Map<KafkaTopicPartition, Long> offsets = new HashedMap();
    offsets.put(new KafkaTopicPartition("maxwell_new", 0), 11111111l);
    offsets.put(new KafkaTopicPartition("maxwell_new", 1), 222222l);
    offsets.put(new KafkaTopicPartition("maxwell_new", 2), 33333333l);
    
    /**
    * Flink从topic中最初的数据开始消费
    */
    consumer.setStartFromEarliest();
    
    /**
    * Flink从topic中指定的时间点开始消费,指定时间点之前的数据忽略
    */
    consumer.setStartFromTimestamp(1559801580000l);
    
    /**
    * Flink从topic中指定的offset开始,这个比较复杂,需要手动指定offset
    */
    consumer.setStartFromSpecificOffsets(offsets);
    
    /**
    * Flink从topic中最新的数据开始消费
    */
    consumer.setStartFromLatest();
    
    /**
    * Flink从topic中指定的group上次消费的位置开始消费,所以必须配置group.id参数
    */
    consumer.setStartFromGroupOffsets();

    作者:香山上的麻雀
    链接:https://www.jianshu.com/p/b753527b91a6
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    本文来自博客园,作者:秋华,转载请注明原文链接:https://www.cnblogs.com/qiu-hua/p/13680639.html

  • 相关阅读:
    解决Qt creator无法输入中文
    JSP 问题总结
    oracle锁与死锁概念,阻塞产生的原因以及解决方案
    QT学习记录
    使用函数式接口
    使用函数式接口来传递行为
    Prototype(原型)
    Singleton(单例)
    Factory
    Template
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/13680639.html
Copyright © 2020-2023  润新知