关于flink kafkaconsumer的偏移量存储位置测试

目录

偏移量存储位置:

偏移量读取顺序:

 代码测试:

生产数据流程:

运行效果:


偏移量存储位置:

1、如果设置了状态后端和checkpoint机制,同时有下面设置:

     FlinkKafkaConsumer.setCommitOffsetsOnCheckpoints(true)

    (上面代码表示每次checkpoint的时候把组消费偏移量提交到kafka,默认为true)

     那么组消费偏移量会记录到  状态后端kafka

2、如果设置了状态后端和checkpoint机制,同时有下面设置:

     FlinkKafkaConsumer.setCommitOffsetsOnCheckpoints(false)

     那么组消费偏移量只会记录到  状态后端 

偏移量读取顺序:

 先从状态后端读,如果没有设置状态后端就从kafka读,如果kafka没有记录组消费偏移量,   只能从 earliest或者latest或者timestamp读。

 代码测试:

flink版本:1.12.1,idea直接运行

public class KafkaOffsetValidate0 {
    public static void main(String[] args) {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.enableCheckpointing(1000);
        env.setStateBackend(new FsStateBackend("file:///D:/flink-state/validate1"));
        env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
        Properties p = new Properties();
        p.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"127.0.0.1:9092");
        p.put(ConsumerConfig.GROUP_ID_CONFIG,"test");
        //从最开始位置消费
        p.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,"earliest");
        //偏移量交给flink管理
        p.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG,"false");
        FlinkKafkaConsumer<String> kafkasource = new FlinkKafkaConsumer<>("offset-validate",
                new SimpleStringSchema(),p);
        //checkpoint时是否提交组消费偏移量默认为true
        //表示每次checkpoint的时候都要把组消费偏移量提交到kafka
        //当没有状态后端就会读这里偏移量,优先读取状态后端的偏移量
        //这里设置为false方便验证问题
        //用命令sh kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group test查看组消费偏移量
        kafkasource.setCommitOffsetsOnCheckpoints(false);
        DataStream<String> datasource = env.addSource(kafkasource, TypeInformation.of(String.class));
        datasource.map(new MapFunction<String, String>() {
            @Override
            public String map(String s) throws Exception {
                System.out.println(s);
                if("exception".equals(s)){
                    double i = 1 / 0;
                }
                return s;
            }
        },TypeInformation.of(String.class)).print();
        env.execute("test");
    }
}

kafka脚本说明:

创建主题:sh kafka-topics.sh --zookeeper 127.0.0.1 --create --topic offset-validate --partitions 1 --replication-factor 1
生产数据:sh kafka-console-producer.sh --broker-list 127.0.0.1:9092 --topic offset-validate
查看主题已有消息量:sh kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list 127.0.0.1:9092 --topic offset-validate --time -1
查看消费组偏移量:sh kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group test

生产数据流程:

输入1,重启程序,1还会再被消费和打印输出。

答案:关闭程序时没有savepoint,启动程序时也没有指定从哪个checkpoint点恢复,同时组消费偏移量没有在checkpoint的时候记录到kafka,只能从头消费处理。
当输入exception时,程序抛出异常,但程序没有停止运行,还知道checkpoint点在哪,数据1没有被重复消费,但数据exception会被重复消费,然后再出异常,再重复消费,再出异常,不断循环。。。

运行效果:

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flink 中,可以通过 `KafkaConsumer` 提供的 `FlinkKafkaConsumer` 来消费 Kafka 中的数据。而保存消费 Kafka偏移量可以使用 Flink 提供的 `FlinkKafkaConsumer` 的 `enableCheckpointing` 方法来实现。 具体做法如下: 1. 在创建 `FlinkKafkaConsumer` 对象时,设置 `enableCheckpointing` 方法开启 Flinkcheckpoint 机制。 ```java FlinkKafkaConsumer<String> kafkaConsumer = new FlinkKafkaConsumer<>(topic, new SimpleStringSchema(), properties); kafkaConsumer.setStartFromEarliest(); kafkaConsumer.setCommitOffsetsOnCheckpoints(true); env.enableCheckpointing(5000); ``` 2. 设置 `setCommitOffsetsOnCheckpoints` 方法为 `true`,表示 Flink 在进行 checkpoint 时会自动提交当前消费 Kafka偏移量。 3. 在 Flink 应用程序中,可以通过实现 `CheckpointedFunction` 接口来手动管理 Kafka 偏移量的保存和恢复。 ```java public class KafkaConsumer implements SourceFunction<String>, CheckpointedFunction { private transient ListState<Long> offsetState; private volatile boolean isRunning = true; private long offset = 0L; @Override public void snapshotState(FunctionSnapshotContext context) throws Exception { offsetState.clear(); offsetState.add(offset); } @Override public void initializeState(FunctionInitializationContext context) throws Exception { ListStateDescriptor<Long> offsetStateDescriptor = new ListStateDescriptor<>("offsets", Long.class); offsetState = context.getOperatorStateStore().getListState(offsetStateDescriptor); if (context.isRestored()) { for (Long offset : offsetState.get()) { this.offset = offset; } } } @Override public void run(SourceContext<String> ctx) throws Exception { while (isRunning) { ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000)); for (ConsumerRecord<String, String> record : records) { offset = record.offset(); ctx.collect(record.value()); } } } } ``` 在 `snapshotState` 方法中,将当前消费 Kafka偏移量保存到 `offsetState` 状态变量中。在 `initializeState` 方法中,可以从状态变量中恢复保存的偏移量。在 `run` 方法中,每次消费 Kafka 中的数据时,都会更新 `offset` 变量为当前消费的偏移量。 这样,当 Flink 应用程序出现故障,重新启动时,就可以从保存的偏移量处继续消费 Kafka 中的数据,避免了数据的重复消费。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值