Почему в Apache Kafka каждому потребителю (Consumer) в группе должна назначаться уникальная партиция?

«Почему в Apache Kafka каждому потребителю (Consumer) в группе должна назначаться уникальная партиция?» — вопрос из категории Брокеры сообщений, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Это фундаментальное правило масштабирования потребления в Kafka. Одна партиция может обрабатываться только одним потребителем в рамках consumer-группы. Это обеспечивает:

  1. Гарантированный порядок сообщений: Kafka гарантирует порядок доставки сообщений только в пределах одной партиции. Если бы несколько потребителей читали из одной партиции, порядок обработки между ними был бы неопределенным.
  2. Масштабируемость обработки: Количество параллельно работающих потребителей ограничено количеством партиций в топике. Чтобы увеличить пропускную способность обработки, нужно увеличивать количество партиций.
  3. Отсутствие координации: Потребителям не нужно координироваться между собой за доступ к сообщению. Брокер сам назначает партиции потребителям в группе (rebalance).

Как это работает:

  • Группа потребителей (group.id) подписывается на топик.
  • Координатор группы назначает каждой партиции топика ровно одного потребителя из группы.
  • Если потребителей больше, чем партиций, «лишние» потребители останутся без работы (idle).

Пример настройки и последствия:

Properties props = new Properties();
props.put("bootstrap.servers", "kafka:9092");
props.put("group.id", "order-processors"); // Группа потребителей
props.put("key.deserializer", StringDeserializer.class.getName());
props.put("value.deserializer", StringDeserializer.class.getName());

KafkaConsumer<String, Order> consumer = new KafkaConsumer<>(props);
consumer.subscribe(List.of("orders")); // Топик с 4 партициями

// Запуск 2 инстансов приложения с этим кодом:
// -> Каждому потребителю будет назначено по 2 партиции.
// Запуск 4 инстансов:
// -> Каждому потребителю будет назначено по 1 партиции.
// Запуск 5 инстансов:
// -> 4 потребителя получат по 1 партиции, 5-й будет простаивать.

Вывод: Связка «одна партиция — один потребитель в группе» — это механизм, обеспечивающий параллельную, упорядоченную и масштабируемую обработку потока сообщений.