kafka指定时间、topic进行消费数据 (kafka 学习【二】)

指定时间和topic进行数据回溯

​
@Resource 
private KafkaConsumer<String,String> kafkaConsumer;

/**
 * 指定时间和topic进行消费数据
 * @param request
 * @throws Exception
 */
public void consumeRecords(CustomKafkaRequest request) throws Exception{
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    Date date = simpleDateFormat.parse(request.getStartTime());
    long startTime =  date.getTime();
    List<TopicPartition> topicPartitions = new ArrayList<>();
    Map<TopicPartition, Long> partitionLongMap = new HashMap<>();
    // 获取topic对应的partition信息
    for (PartitionInfo topicPartition : kafkaConsumer.partitionsFor(request.getTopic())) {
        partitionLongMap.put(new TopicPartition(topicPartition.topic(), topicPartition.partition()), startTime);
        topicPartitions.add(new TopicPartition(topicPartition.topic(),topicPartition.partition()));
    }
    kafkaConsumer.assign(topicPartitions);
    Map<TopicPartition, OffsetAndTimestamp> map = kafkaConsumer.offsetsForTimes(partitionLongMap);
    // 获取topic的partition以及offset信息
    for (Map.Entry<TopicPartition, OffsetAndTimestamp> entry : map.entrySet()) {
        TopicPartition partition = entry.getKey();
        OffsetAndTimestamp value = entry.getValue();
        if(value != null){
            long offset = value.offset();
            kafkaConsumer.seek(partition, offset);
        }
    }
    long endTime = StringUtils.isEmpty(request.getEndTime())? new Date().getTime() : simpleDateFormat.parse(request.getEndTime()).getTime();
    boolean isCancel = false;
    while (!isCancel) {
        ConsumerRecords<String, String> records = kafkaConsumer.poll(Duration.ofSeconds(10));
        for (ConsumerRecord<String, String> record : records) {
            if (record.timestamp() <= endTime) {
                 // do some thing
            } else {
                isCancel = true;
            }
        }
        if(records.isEmpty()){
            isCancel = true;
        }
    }
}

​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!感谢您的提问。针对您的问题,我们可以通过使用 Kafka 的 Consumer API 来消费指定时间范围内的 Kafka Topic 数据。具体的实现方式包括以下几个步骤: 1. 创建 Kafka Consumer 对象 ``` Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); props.put("group.id", "test-group"); props.put("enable.auto.commit", "false"); props.put("auto.offset.reset", "earliest"); props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); ``` 在这个示例代码中,我们创建了一个 Kafka Consumer 对象,并通过指定的参数来配置了该对象的一些属性,包括 Kafka 集群的连接地址、消费者组的 ID、是否自动提交消费位移、以及 Key 和 Value 的反序列化方法等。 2. 订阅 Kafka Topic ``` consumer.subscribe(Collections.singletonList("test-topic"), new ConsumerRebalanceListener() { @Override public void onPartitionsRevoked(Collection<TopicPartition> partitions) { // 消费者失去了分区的所有权,需要处理分区的偏移量 } @Override public void onPartitionsAssigned(Collection<TopicPartition> partitions) { // 消费者重新获得了分区的所有权,可以继续消费数据 } }); ``` 在上述代码中,我们使用 Kafka Consumer 的 `subscribe()` 方法来订阅需要消费Topic,`ConsumerRebalanceListener` 则用于处理在分区发生变化时的情况,例如消费者失去了分区的所有权或重新获得了分区的所有权等。 3. 指定时间范围内的消费位移 ``` Map<TopicPartition, Long> timestampToSearch = new HashMap<>(); for (TopicPartition partition : consumer.assignment()) { timestampToSearch.put(partition, System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(10)); } Map<TopicPartition, OffsetAndTimestamp> offsetAndTimestamp = consumer.offsetsForTimes(timestampToSearch); for (Map.Entry<TopicPartition, OffsetAndTimestamp> entry : offsetAndTimestamp.entrySet()) { TopicPartition partition = entry.getKey(); OffsetAndTimestamp offsetTimestamp = entry.getValue(); if (offsetTimestamp != null) { consumer.seek(partition, offsetTimestamp.offset()); } } ``` 在这个步骤中,我们创建了一个 `Map` 对象 `timestampToSearch`,并将消费者当前订阅的所有分区的消费位移时间戳都设置为 `System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(10)` 表示过去 10 分钟以内的数据。然后,我们通过调用 Kafka Consumer 的 `offsetsForTimes()` 方法来获取指定时间戳之后的消费位移,最后再通过 `seek()` 方法将消费者定位到指定消费位移处,即可开始消费指定时间范围内的 Kafka Topic 数据。 希望上述实现方式能够解决您的问题。如果您有其他的问题或疑问,请随时向我提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值