我有一个主题“橙色”,其中有10个分区,一个消费者组中有2个消费者。我正在使用Spring Kafka。
由于某种原因,我需要不时重新读取数据,我需要重置偏移量。我的监听器实现了ConsumerSeekAware
,在onPartitionsAssigned()
中,我只调用了callback#seekToBeginning
。正如我在日志中看到的来自Kafka Client API(2.3.1)的消息中所述:
重置分区oranges-X to offset 0
的偏移量。对于所有分区来说,这种情况都很好。
但是,实际上只有最后一个分区被重置(9),如果我很幸运,第二个分区(1)也会不时重置。其他所有设备都不会重置。
让我真正头疼的是:如果我从要重置的分区列表中省略了分区9,则所有其他分区都可以很好地重置,并且一切正常。
代码很简单:
class ... implements ConsumerSeekAware {
@Override
public void onPartitionsAssigned(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
...
callback.seekToBeginning(topicPartition.topic(), topicPartition.partition());
}
...
日志:
19 Jun 09:56:49.442] [INFO] [{}] [org.apache.kafka.clients.consumer.internals.SubscriptionState] - [Consumer clientId=orange-0, groupId=avaloq.fints.acpadapter] Resetting offset for partition orange-9 to offset 0.
[19 Jun 09:56:49.443] [INFO] [{}] [org.apache.kafka.clients.consumer.internals.SubscriptionState] - [Consumer clientId=orange-0, groupId=avaloq.fints.acpadapter] Resetting offset for partition orange-8 to offset 0.
[19 Jun 09:56:49.443] [INFO] [{}] [org.apache.kafka.clients.consumer.internals.SubscriptionState] - [Consumer clientId=orange-0, groupId=avaloq.fints.acpadapter] Resetting offset for partition orange-1 to offset 0.
[19 Jun 09:56:49.443] [INFO] [{}] [org.apache.kafka.clients.consumer.internals.SubscriptionState] - [Consumer clientId=orange-0, groupId=avaloq.fints.acpadapter] Resetting offset for partition orange-0 to offset 0.
[19 Jun 09:56:49.443] [INFO] [{}] [org.apache.kafka.clients.consumer.internals.SubscriptionState] - [Consumer clientId=orange-0, groupId=avaloq.fints.acpadapter] Resetting offset for partition orange-3 to offset 0.
[19 Jun 09:56:49.443] [INFO] [{}] [org.apache.kafka.clients.consumer.internals.SubscriptionState] - [Consumer clientId=orange-0, groupId=avaloq.fints.acpadapter] Resetting offset for partition orange-2 to offset 0.
[19 Jun 09:56:49.443] [INFO] [{}] [org.apache.kafka.clients.consumer.internals.SubscriptionState] - [Consumer clientId=orange-0, groupId=avaloq.fints.acpadapter] Resetting offset for partition orange-5 to offset 0.
[19 Jun 09:56:49.443] [INFO] [{}] [org.apache.kafka.clients.consumer.internals.SubscriptionState] - [Consumer clientId=orange-0, groupId=avaloq.fints.acpadapter] Resetting offset for partition orange-4 to offset 0.
[19 Jun 09:56:49.443] [INFO] [{}] [org.apache.kafka.clients.consumer.internals.SubscriptionState] - [Consumer clientId=orange-0, groupId=avaloq.fints.acpadapter] Resetting offset for partition orange-7 to offset 0.
[19 Jun 09:56:49.443] [INFO] [{}] [org.apache.kafka.clients.consumer.internals.SubscriptionState] - [Consumer clientId=orange-0, groupId=avaloq.fints.acpadapter] Resetting offset for partition orange-6 to offset 0.
答案 0 :(得分:0)
我无法复制您的问题。
这是我测试的Spring Boot应用程序:
@SpringBootApplication
public class So62465345Application extends AbstractConsumerSeekAware {
private static final Logger LOG = LoggerFactory.getLogger(So62465345Application.class);
public static void main(String[] args) {
SpringApplication.run(So62465345Application.class, args);
}
@KafkaListener(id = "so62465345", topics = "so62465345")
public void listen(String in) {
System.out.println(in);
}
@Bean
public NewTopic topic() {
return TopicBuilder.name("so62465345").partitions(10).replicas(1).build();
}
@Bean
public ApplicationRunner runner(KafkaTemplate<String, String> template) {
return args -> IntStream.range(0, 9).forEach(i -> template.send("so62465345", i, null,
System.currentTimeMillis() + ":foo:" + i));
}
@Override
public void onPartitionsAssigned(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
LOG.info("Seeking on assignment");
callback.seekToBeginning(assignments.keySet());
}
@Override
public void onIdleContainer(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
LOG.info("Seeking on idle");
callback.seekToBeginning(assignments.keySet());
}
}
spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.listener.idle-event-interval=30000
spring.kafka.listener.poll-timeout=2000
我在onIdleContainer
中设置了一个断点,并且使用kafka-console-consumer
,我发现偏移量直到下一个poll()
才真正重置。
Seeking to EARLIEST offset of partition so62465345-1
会在执行搜索时出现,但是Resetting offset for partition so62465345-0 to offset 0
会在我们再次调用poll()
之前才会出现(然后实际重置偏移量)。
因此,我确实发现搜索不在当前轮询中发生,该轮询返回0条记录,但是下一个轮询从头开始。