Ответ
В модели Kafka один потребитель (Consumer) читает сообщения строго из одной партиции. Назначение нескольких потребителей на одну партицию нарушает базовые гарантии Kafka и приводит к проблемам.
Почему это плохая практика:
-
Нарушение гарантии порядка: Kafka гарантирует порядок доставки сообщений только в пределах одной партиции. Если два независимых потребителя читают одну партицию, они будут конкурировать за смещения (offsets), и сообщения будут обрабатываться в произвольном порядке.
-
Дублирование обработки: Потребители не знают о смещениях друг друга. Сообщение, прочитанное и обработанное одним потребителем, может быть снова прочитано другим, если первый не успел зафиксировать смещение.
-
Отсутствие балансировки нагрузки: Потребители не скоординированы. Один может прочитать и обработать все сообщения, пока другой простаивает.
Правильный подход: Consumer Groups
- Потребители объединяются в Consumer Group (указывается в
group.id). - Каждая партиция топика назначается ровно одному потребителю внутри группы.
- При добавлении или удалении потребителя из группы происходит ребалансировка партиций.
Пример корректной настройки Consumer Group:
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "order-processors"); // Имя группы потребителей
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("enable.auto.commit", "true"); // Автоматическая фиксация смещений
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("orders-topic")); // Подписка на топик
// Для топика с 4 партициями и группой из 2 потребителей:
// - Consumer 1 получит партиции 0 и 1.
// - Consumer 2 получит партиции 2 и 3.
// Каждое сообщение будет обработано ровно один раз в порядке его поступления в партицию.
Вывод: Для масштабирования обработки увеличивайте количество партиций в топике и добавляйте потребителей в одну группу, а не назначайте несколько потребителей на одну партицию.