У меня есть одна тема 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 машины.
Дополнительные входные данные:- Я могу воспроизвести проблему с приведенным ниже сценарием.
- Создайте три темы A (1-Partition), B (10-Partition) и C (10-Partition)
- KafkaStreams получает сообщение от A и отправляет сообщения в B и C.
- Отправил около 100 сообщений в тему. KafkaStreams используется и передается в темы B&C. Я вижу, что сообщения распределены по всем разделам B&C (т.е. 10 разделов содержат около 10 сообщений).
- Я создал единственную тему KafkaConsumer, Consuming B. Теперь я вызываю метод offsetForTimes со всеми разделами, а отметка времени составляет 5 минут минус текущий.
- гарантирует, что Consumer.assignment() возвращает все разделы до offsetForTimes.
- offsetForTimes возвращает один раздел со смещенной позицией, но когда я вызываю метод Consumer.poll, он также возвращает сообщения из других разделов.
С использованием версии apache kafka - 2.11-2.2.0 jar клиентов Kafka - 2.0.1
Цените помощь заранее.
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));
}
}
Похожие вопросы
Связанные вопросы
Новые вопросы
apache-kafka
Apache Kafka - это распределенная потоковая платформа, предназначенная для хранения и обработки высокопроизводительных потоков данных.
assignment()
, чтобы убедиться, что вашему потребителю действительно назначены разделы. Отредактируйте вопрос, чтобы точно показать, что вы получаете вoffsets
.