flink 1.14版本kafkaconnector问题

flink 1.14版本kafkaconnector问题

Version
flink1.14.5
kafka2.2.1

kafkasource

kafkasource指定offset时,除了earlest和直接指定offset 外latest与时间戳处消费并不生效,reseting offset总是指定当前的offset,看源码并没有找到问题出在哪里,因此退而求,提前获取该消费者组的offset,传入offset实现。

public static OffsetsInitializer getTopicPartitons(OffsetUtils offsetUtil, String groupId, String... topics) {
        prop.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
        OffsetsInitializer offsetsInitializer = OffsetsInitializer.earliest();
        if (offsetUtil.getOffestEnum().equals(OffestEnum.EARLIEST)) {
            offsetsInitializer = OffsetsInitializer.earliest();
        } else if (OffestEnum.LATEST.equals(offsetUtil.getOffestEnum())) {
            KafkaConsumer<String, String> consumer = new KafkaConsumer<>(prop);
            HashMap<TopicPartition, Long> topicPartitions = new HashMap<>();
            for (String topic : topics) {
                List<PartitionInfo> partitionInfos = consumer.partitionsFor(topic);
                Set<TopicPartition> topicPartitionList = new HashSet<>();
                for (PartitionInfo partitionInfo : partitionInfos) {
                    TopicPartition topicPartition = new TopicPartition(topic, partitionInfo.partition());
                    topicPartitionList.add(topicPartition);
                }
                HashMap<TopicPartition, Long> tmepMaps = new HashMap<>();
                Map<TopicPartition, OffsetAndMetadata> committed = consumer.committed(topicPartitionList);
                Map<TopicPartition, Long> begaininge = consumer.endOffsets(topicPartitionList);
                boolean flag = false;
                for (TopicPartition topicPartition : committed.keySet()) {
                    if (committed.get(topicPartition) == null) {
                        flag = true;
                        break;
                    }
                }
                if (!flag) {
                    for (TopicPartition topicPartition : committed.keySet()) {
                        tmepMaps.put(topicPartition, committed.get(topicPartition).offset());
                    }
                } else {
                    System.out.println("-----------------无法找到上次提交offset,建议传入时间----------------------------");
                    for (TopicPartition topicPartition : begaininge.keySet()) {
                        tmepMaps.put(topicPartition, begaininge.get(topicPartition));
                    }
                }
                for (TopicPartition topicPartition:topicPartitions.keySet()){
                    System.out.println(topicPartition.topic()+":"+topicPartition.partition()+":"+topicPartitions.get(topicPartition));
                }
                topicPartitions.putAll(tmepMaps);
            }
            offsetsInitializer = OffsetsInitializer.offsets(topicPartitions);
        } else if (OffestEnum.TIMESTAMP.equals(offsetUtil.getOffestEnum())) {
            KafkaConsumer<String, String> consumer = new KafkaConsumer<>(prop);
            Map<TopicPartition, Long> topicPartitions = new HashMap<>();
            for (String topic : topics) {
                List<PartitionInfo> partitionInfos = consumer.partitionsFor(topic);
                ArrayList<TopicPartition> topicPartitionList = new ArrayList<>();
                Map<TopicPartition, Long> tmepMaps = new HashMap<TopicPartition, Long>();
                for (PartitionInfo partitionInfo : partitionInfos) {
                    TopicPartition topicPartition = new TopicPartition(topic, partitionInfo.partition());
                    topicPartitionList.add(topicPartition);
                    tmepMaps.put(topicPartition, offsetUtil.getDateO());
                }
                Map<TopicPartition, OffsetAndTimestamp> tme = consumer.offsetsForTimes(tmepMaps);
                Map<TopicPartition, Long> tmepMaps1 = new HashMap<TopicPartition, Long>();
                boolean flag = false;
                for (TopicPartition topicPartition : tme.keySet()) {
                    if (tme.get(topicPartition) == null) {
                        topicPartitions = consumer.endOffsets(topicPartitionList);
                        flag = true;
                        System.out.println("------------------------无法根据时间戳消费,将从最新offset消费----------------------------");
                        break;
                    }
                }
                if (!flag) {
                    for (TopicPartition topicPartition : tme.keySet()) {
                        tmepMaps1.put(topicPartition, tme.get(topicPartition).offset());
                    }
//                    topicPartitions.clear();
                    topicPartitions.putAll(tmepMaps1);
                }
            }
            for (TopicPartition topicPartition:topicPartitions.keySet()){
                System.out.println(topicPartition.topic()+":"+topicPartition.partition()+":"+topicPartitions.get(topicPartition));
            }
            offsetsInitializer = OffsetsInitializer.offsets(topicPartitions);
        }
        if (offsetsInitializer.equals(OffsetsInitializer.earliest()) && !offsetUtil.getOffestEnum().equals(OffestEnum.EARLIEST)) {
            throw new NullPointerException("params is not true");
        }
        return offsetsInitializer;
    }

这样传入kafkaoffset可以解决。

kafkasink

当我们使用上方展示kafkasource时,并没有提前获取offset时,kafkasink 部分消息写入,不同时间写入相同消息时间戳不变,一直是该条数据第一次进入kafka时间,很奇怪,最终只能手写一个kafkaproducer,手动传入时间戳。最后传入方法kafkasource.setStartingOffset 自取后,这个现象现在暂时没有再次遇到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flink 1.14 中,要消费 Kafka 中的数据,需要使用 FlinkKafka Connector。以下是一个简单的 Flink 1.14 消费 Kafka 数据的示例: ```java import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer; import org.apache.flink.streaming.util.serialization.SimpleStringSchema; import java.util.Properties; public class KafkaConsumerExample { public static void main(String[] args) throws Exception { // set up the execution environment final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // configure Kafka properties Properties kafkaProps = new Properties(); kafkaProps.setProperty("bootstrap.servers", "localhost:9092"); kafkaProps.setProperty("group.id", "my-group"); // create a Kafka consumer FlinkKafkaConsumer<String> kafkaConsumer = new FlinkKafkaConsumer<>("my-topic", new SimpleStringSchema(), kafkaProps); // add the Kafka consumer as a source to the Flink program DataStream<String> kafkaDataStream = env.addSource(kafkaConsumer); // print the Kafka data to the console kafkaDataStream.print(); // execute the Flink program env.execute("Kafka Consumer Example"); } } ``` 在此示例中,我们首先设置了执行环境,然后配置了 Kafka 属性。接下来,我们创建了一个 FlinkKafkaConsumer 对象,并将其作为源添加到 Flink 程序中。最后,我们将 Kafka 数据打印到控制台并执行 Flink 程序。请注意,此示例中使用的是 SimpleStringSchema,这意味着数据以字符串形式传递。如果您的数据采用不同的格式,请相应地更改序列化程序。 注意:在使用 Flink 1.14 消费 Kafka 数据时,需要确保与您使用的 Kafka 版本兼容的 Flink Kafka Connector 版本Flink 官方文档提供了有关版本兼容性的详细信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值