Kafka StickyAssignor прервал доставку одному потребителю в группе - PullRequest
0 голосов
/ 08 июня 2018

У меня есть тема с одним разделом и двумя процессами потребителей, которые образуют группу потребителей.

Таким образом, сообщение всегда доставляется одному потребителю.StickyAssignor используется для того, чтобы отдавать предпочтение потребителям, которые уже назначены разделу при ребалансировке.

Я немного поиграл с этой настройкой и обнаружил, что при определенных обстоятельствах сообщения доставляются обоим потребителям, что нарушаетНазначение группы потребителей.

Сценарий следующий:

  1. Запуск потребителя C1
  2. C1 начинает получать сообщения
  3. Запуск потребителя C2
  4. C2 не получает сообщений - благодаря стратегии StickyAssignor, которая предпочитает процесс C1
  5. Freeze C1 - (с использованием отладчика Java - остановка всех потоков)
  6. C2 вступает во владение - начинает получать сообщения
  7. Разморозить процесс C1
  8. Теперь и C1, и C2 получают сообщения несмотря на то, что находятся в одной группе

При использовании RangeAssignor / RoundRobinAssignor, этоне происходит.

Я что-то упустил или это ошибка в Kafka?

Вот мой потребительский код:

Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "test");
props.put("client.id", consumerId);
props.put("enable.auto.commit", "false");
props.put("auto.commit.interval.ms", "1000");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("partition.assignment.strategy", StickyAssignor.class.getName());
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);

consumer.subscribe(Collections.singleton("my-events"));



while (true) {
    ConsumerRecords<String, String> records = consumer.poll(100);
    for (ConsumerRecord<String, String> record : records)
        System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
}
...