以下内容翻译自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的配置则会完全被忽略。