Я пытаюсь реализовать базовый сценарий, перечитать тему с начала (хотя бы 1 сообщение), и я столкнулся с неожиданным поведением.
Предположим, что в 1 теме раздела содержится ровно 1 миллион сообщений, 1 потребитель со смещением уже зафиксирован где-то посередине, активных производителей нет.
Сначала я попробовал
consumer.subscribe(Collections.singletonList(topic));
consumer.seekToBeginning(Collections.emptySet());
consumer.poll(Duration.ofMillis(longTimeout)); //no loop to simplify
И это не работает (нет опрошенных сообщений). Я читал, что seekToBeginning
ленив (и это нормально), но, оказывается, seekToBeginning
никак не влияет, потому что ему нужно назначить разделы, что произойдет только при первом опросе. Должно ли это быть описано в документации, или я пропустил это?
Тогда я попробовал
consumer.subscribe(Collections.singletonList(topic));
consumer.poll(Duration.ofMillis(assignTimeout));
consumer.seekToBeginning(Collections.emptySet());
consumer.poll(Duration.ofMillis(longTimeout));//no loop to simplify
И получается, это зависит от assignTimeout
. Этого должно быть достаточно для завершения процесса присоединения. Это время может меняться, и на него нельзя полагаться.
Тогда я предоставил ConsumerRebalanceListener
с
@Override
public void onPartitionsAssigned(Collection<TopicPartition> partitions) {
consumer.seekToBeginning(partitions);
}
и один poll
осталось. И, наконец, это похоже на работу.
Итак, вопросы:
- Является ли
seekToBeginning
сразу после subscribe
бесполезным? Должно ли это быть документировано?
- Надежно ли решение с
ConsumerRebalanceListener
? Гарантирует ли это, что никакие сообщения из среднего (зафиксированного смещения) не будут опрошены, прежде чем будет применен поиск?