我们如何在给定的时间范围内阅读卡夫卡主题?

时间:2014-07-15 21:23:59

标签: apache-kafka

我需要从Kafka主题中读取给定时间范围内的消息。我能想到的解决方案是首先找出时间范围开始时的最大偏移量,然后继续使用消息,直到超出时间范围结束的所有分区的偏移量。有没有更好的方法来解决这个问题?谢谢!

2 个答案:

答案 0 :(得分:0)

你的意思是"时间范围"?

消息中队列中的消息或时间戳中的时间范围? : - )

我要考虑的是使用Kafka Streams和窗口流,并且假设当前时间戳的取消消息是范围中的消息,然后将消息从流中取出,然后考虑消息,否则只是忽略它。

另一方面,如果你在消息中考虑时间戳,那么对流的小扩展(在java DSL .filter()方法中)将很好地为你过滤掉消息。你只需要制定好的谓词。

请参阅:Kafka Streams (Confluent)Kafka Streams (Apache)

答案 1 :(得分:0)

好吧,您绝对必须先搜索适合时间范围的开头的第一个偏移量。

这可以使用KafkaConsumer#offsetsForTimes方法来完成。

该方法接受Map<TopicPartition, Long(timestamp)>的映射,并返回Map<TopicPartition, OffsetAndTimestamp>,其中OffsetAndTimestamp中的时间戳是时间戳为等于或大于的第一条消息的时间戳然后指定一个。

从那里,您可以将消费者分配给返回的偏移量,并进行迭代直到记录中的时间戳超过时间范围的结束为止。

一些伪代码:

static void main(String[] args) {
    String topic = args[1];
    long timestampBeginning = Long.parseLong(args[2]);
    long timestampEnd = Long.parseLong(args[3]);
    TopicPartition partition = new TopicPartition(topic, 0);

    Consumer<Object, Object> consumer = createConsumer();

    long beginningOffset = consumer.offsetsForTimes(
            Collections.singletonMap(partition, timestampBeginning))
                    .get(partition).offset();

    consumer.assign(Collections.singleton(partition)); // must assign before seeking
    consumer.seek(partition, beginningOffset);

    for (ConsumerRecord<Object, Object> record : consumer.poll()) {
        if (record.timestamp() > timestampEnd) {
            break; // or whatever
        }

        // handle record
    }
}