KafkaConsumer 0.10 сообщение об ошибке API Java: нет текущего назначения для раздела
Я использую KafkaConsumer 0.10 API-интерфейса Java. Я хочу потреблять из определенного раздела и определенного смещения. Я посмотрел вверх и обнаружил, что есть метод поиска, но его исключение. У кого-нибудь был подобный вариант использования или решение ?
код:
KafkaConsumer<String, byte[]> consumer = new KafkaConsumer<>(consumerProps);
consumer.seek(new TopicPartition("mytopic", 1), 4);
исключение
java.lang.IllegalStateException: No current assignment for partition mytopic-1
at org.apache.kafka.clients.consumer.internals.SubscriptionState.assignedState(SubscriptionState.java:251)
at org.apache.kafka.clients.consumer.internals.SubscriptionState.seek(SubscriptionState.java:276)
at org.apache.kafka.clients.consumer.KafkaConsumer.seek(KafkaConsumer.java:1135)
at xx.xxx.xxx.Test.main(Test.java:182)
2 ответов
перед seek()
сначала надо subscribe()
на тему или assign()
раздел Темы для потребителя. Также имейте в виду, что subscribe()
и assign()
ленивы - таким образом, вам также нужно сделать "фиктивный вызов" в poll()
прежде чем вы можете использовать seek()
.
Примечание: начиная с Кафки 2.0, новый
poll(Duration timeout)
является асинхронным, и не гарантируется, что у вас есть полное назначение, когдаpoll
возвращает. Таким образом, вам может потребоваться проверить назначение перед использованиемseek()
иpoll
еще раз, чтобы обновить назначение. (Ср. КИП-266 дополнительные сведения)
если вы используете subscribe()
, вы используете управление группами: таким образом, вы можете запустить несколько потребителей, используя тот же group.id
и все разделы темы будут назначены равномерно всем потребителям в группе автоматически (каждый раздел будет назначен одному потребителю в группе).
если вы хотите прочитать конкретные разделы, вам нужно использовать ручное назначение через assign()
. Это позволяет выполнять любое задание.
кстати: KafkaConsumer
имеет очень длинный подробный класс JavaDoc, включая примеры. Стоит прочитать.
Если вы не хотите использовать () и получить записи карты, и изменить само смещение. Кафка версия 0.11 Попробуйте это:
...
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("Test_topic1", "Test_topic2"));
List<TopicPartition> partitions =consumer.partitionsFor("Test_topic1").stream().map(part->{TopicPartition tp = new TopicPartition(part.topic(),part.partition()); return tp;}).collect(Collectors.toList());
Field coordinatorField = consumer.getClass().getDeclaredField("coordinator");
coordinatorField.setAccessible(true);
ConsumerCoordinator coordinator = (ConsumerCoordinator)coordinatorField.get(consumer);
coordinator.poll(new Date().getTime(), 1000);//Watch out for your local date and time settings
consumer.seekToBeginning(partitions); //or other seek
для мероприятий. Это гарантирует, что координатор известен и что потребитель присоединился к группе (если он использует управление группой). Это также обрабатывает периодические фиксации смещения, если они включены.