offset什么时候提交
主要看是否开启了checkpoint
- 开启了checkpoint
情况1:
用户通过调用 consumer上的setCommitOffsetsOnCheckpoints(true) 方法来启用 offset 的提交(默认情况下为 true )
那么当 checkpointing 完成时,Flink Kafka Consumer 将提交的 offset 存储在 checkpoint 状态中。
这确保 Kafka broker 中提交的 offset 与 checkpoint 状态中的 offset 一致。
注意,在这个场景中,Properties 中的自动定期 offset 提交设置会被完全忽略。此情况使用的是ON_CHECKPOINTS
情况2:
用户通过调用 consumer 上的 setCommitOffsetsOnCheckpoints(“false”) 方法来禁用 offset 的提交,则使用DISABLED模式提交offset - 未开启checkpoint
Flink Kafka Consumer 依赖于内部使用的 Kafka client 自动定期 offset 提交功能,因此,要禁用或启用 offset 的提交
情况1:
配置了Kafka properties的参数配置了"enable.auto.commit" = "true"或者 Kafka 0.8 的 auto.commit.enable=true,使用KAFKA_PERIODIC模式提交offset,即自动提交offset
情况2:没有配置enable.auto.commit参数,使用DISABLED模式提交offset,这意味着kafka不知道当前的消费者组的消费者每次消费的偏移量
public class KafkaConnector {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment senv = StreamExecutionEnvironment.getExecutionEnvironment();
// 开启checkpoint,时间间隔为毫秒
senv.enableCheckpointing(5000L);
// 选择状态后端
senv.setStateBackend((StateBackend) new FsStateBackend("file:///E://checkpoint"));
//senv.setStateBackend((StateBackend) new FsStateBackend("hdfs://kms-1:8020/checkpoint"));
Properties props = new Properties();
// kafka broker地址
props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
// 仅kafka0.8版本需要配置
props.put("zookeeper.connect", "node01:2181,node02:2181,node03:2181");
// 消费者组
props.put("group.id", "test");
// 自动偏移量提交
props.put("enable.auto.commit", true);
// 偏移量提交的时间间隔,毫秒
props.put("auto.commit.interval.ms", 5000);
// kafka 消息的key序列化器
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
// kafka 消息的value序列化器
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
// 指定kafka的消费者从哪里开始消费数据
// 共有三种方式,
// #earliest
// 当各分区下有已提交的offset时,从提交的offset开始消费;
// 无提交的offset时,从头开始消费
// #latest
// 当各分区下有已提交的offset时,从提交的offset开始消费;
// 无提交的offset时,消费新产生的该分区下的数据
// #none
// topic各分区都存在已提交的offset时,
// 从offset后开始消费;
// 只要有一个分区不存在已提交的offset,则抛出异常
props.put("auto.offset.reset", "latest");
FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>(
"topic_name",
new SimpleStringSchema(),
props);
//设置checkpoint后在提交offset,即oncheckpoint模式
// 该值默认为true,
consumer.setCommitOffsetsOnCheckpoints(true);
// 最早的数据开始消费
// 该模式下,Kafka 中的 committed offset 将被忽略,不会用作起始位置。
//consumer.setStartFromEarliest();
// 消费者组最近一次提交的偏移量,默认。
// 如果找不到分区的偏移量,那么将会使用配置中的 auto.offset.reset 设置
//consumer.setStartFromGroupOffsets();
// 最新的数据开始消费
// 该模式下,Kafka 中的 committed offset 将被忽略,不会用作起始位置。
//consumer.setStartFromLatest();
// 指定具体的偏移量时间戳,毫秒
// 对于每个分区,其时间戳大于或等于指定时间戳的记录将用作起始位置。
// 如果一个分区的最新记录早于指定的时间戳,则只从最新记录读取该分区数据。
// 在这种模式下,Kafka 中的已提交 offset 将被忽略,不会用作起始位置。
//consumer.setStartFromTimestamp(1585047859000L);
// 为每个分区指定偏移量
/*Map<KafkaTopicPartition, Long> specificStartOffsets = new HashMap<>();
specificStartOffsets.put(new KafkaTopicPartition("topic_name", 0), 23L);
specificStartOffsets.put(new KafkaTopicPartition("topic_name", 1), 31L);
specificStartOffsets.put(new KafkaTopicPartition("topic_name", 2), 43L);
consumer1.setStartFromSpecificOffsets(specificStartOffsets);*/
/**
*
* 请注意:当 Job 从故障中自动恢复或使用 savepoint 手动恢复时,
* 这些起始位置配置方法不会影响消费的起始位置。
* 在恢复时,每个 Kafka 分区的起始位置由存储在 savepoint 或 checkpoint 中的 offset 确定
*
*/
DataStreamSource<String> source = senv.addSource(consumer);
// TODO
source.print();
senv.execute("test kafka connector");
}
}