У меня есть одна тема kafka с 8 разделами, подписка на тему от одного потребителя, и у меня есть уникальная группа потребителей для потребителя. Теперь я попытался использовать только последние сообщения (в моем случае за 3 минуты до текущего времени) из всех разделов. Я использовал метод offsetForTimes, как показано ниже.

List<PartitionInfo> partitionInfos = consumer.partitionsFor(topic);
List<TopicPartition> topicPartions = partitionInfos.stream().......collect(Collectors.toList());
Long value = Instant.now().minus(120,ChronoUnit.SECONDS).toEpochMillis();
Map<TopicPartion,Long> topicPartitionTime = topicPartions.stream().collect(COllectors.toMap(tp -> tp,(value)));
Map<TopicPartition, OffsetAndTimeStamp> offsets = consumer.offsetsForTimes(topicPartitionTime);

Теперь вопрос в offsetsForTimes возвращает только одну или две позиции смещения разделов и возвращает null для остальных.

Я хочу использовать последние сообщения всех разделов, а не один или два раздела.

Я также пробовал ниже

consumer.unsubscribe();
consumer.assign(allPartitions);
Map<TopicPartition, OffsetAndTimeStamp> offsets = consumer.offsetsForTimes(topicPartitionTime);

Но по-прежнему получает только одну или две позиции смещения. В худшем случае иногда нулевые смещения для всех разделов.

Если offsetForTimes работает только с одним/двумя разделами, как опросить последние записи всех разделов от одного потребителя?

EDITED: я использую кластер Kafka. 8 разделов расшарены на 3-4 машины.

Дополнительные входные данные:- Я могу воспроизвести проблему с приведенным ниже сценарием.

  1. Создайте три темы A (1-Partition), B (10-Partition) и C (10-Partition)
  2. KafkaStreams получает сообщение от A и отправляет сообщения в B и C.
  3. Отправил около 100 сообщений в тему. KafkaStreams используется и передается в темы B&C. Я вижу, что сообщения распределены по всем разделам B&C (т.е. 10 разделов содержат около 10 сообщений).
  4. Я создал единственную тему KafkaConsumer, Consuming B. Теперь я вызываю метод offsetForTimes со всеми разделами, а отметка времени составляет 5 минут минус текущий.
  5. гарантирует, что Consumer.assignment() возвращает все разделы до offsetForTimes.
  6. offsetForTimes возвращает один раздел со смещенной позицией, но когда я вызываю метод Consumer.poll, он также возвращает сообщения из других разделов.

С использованием версии apache kafka - 2.11-2.2.0 jar клиентов Kafka - 2.0.1

Цените помощь заранее.

1
PrabaharanKathiresan 5 Дек 2019 в 20:41

1 ответ

Я не могу воспроизвести ваше состояние; единственный раз, когда я получаю null для смещения, это когда для этого раздела нет фиксированного смещения. например У меня 10 разделов, но запись только на 8:

@SpringBootApplication
public class So59200574Application implements ConsumerSeekAware {

    public static void main(String[] args) {
        SpringApplication.run(So59200574Application.class, args);
    }

    @Bean
    public NewTopic topic() {
        return TopicBuilder.name("so59200574").partitions(10).replicas(1).build();
    }

    @KafkaListener(id = "so59200574", topics = "so59200574")
    public void listen(String in) {
        System.out.println(in);
    }

    @Bean
    public ConsumerAwareRebalanceListener rebal() {
        return new ConsumerAwareRebalanceListener() {

            @Override
            public void onPartitionsAssigned(Consumer<?, ?> consumer, Collection<TopicPartition> partitions) {
                Map<TopicPartition, Long> timestampsToSearch = new HashMap<>();
                final long tenSecondsAgo = System.currentTimeMillis() - 10_000L;
                partitions.forEach(tp -> timestampsToSearch.computeIfAbsent(tp, tp1 -> tenSecondsAgo));
                System.out.println(consumer.offsetsForTimes(timestampsToSearch));
            }

        };
    }

    @Bean
    public ApplicationRunner runner(KafkaTemplate<String, String> template) {
        return args -> IntStream.range(0, 8).forEach(i -> template.send("so59200574", i, null, "foo" + i));
    }

}
0
Gary Russell 6 Дек 2019 в 17:34
Гэри, я могу воспроизвести сценарий на своем локальном компьютере. Я отредактировал вопрос с дополнительными входами.
 – 
PrabaharanKathiresan
7 Дек 2019 в 19:33
Попробуйте вызвать assignment(), чтобы убедиться, что вашему потребителю действительно назначены разделы. Отредактируйте вопрос, чтобы точно показать, что вы получаете в offsets.
 – 
Gary Russell
7 Дек 2019 в 19:45
Спасибо за помощь. В вопрос добавлен раздел дополнительных входных данных.
 – 
PrabaharanKathiresan
7 Дек 2019 в 19:59
Для меня это не имеет смысла. Если вы подтолкнете небольшой проект куда-нибудь, демонстрирующий такое поведение; Я посмотрю на следующей неделе.
 – 
Gary Russell
7 Дек 2019 в 20:30