Что такое consumer group в Kafka и как она помогает разделять нагрузку между потребителями?
Что проверяют
Понимаете ли вы, что масштабирование чтения в Kafka упирается не в число процессов, а в число партиций. Для .NET-разработчика за вопросом стоит практика: как разложить обработку на несколько экземпляров сервиса и не получить ни простаивающих потребителей, ни дублей в базе.
Как отвечать
Consumer group это набор потребителей с одинаковым GroupId, между которыми брокер делит партиции топика. Партиция в любой момент закреплена ровно за одним участником, поэтому параллелизм чтения ограничен числом партиций. Запустили шесть экземпляров на топик с тремя партициями, работать будут три, остальные простаивают.
Смещения хранятся на брокере и привязаны к паре группа плюс партиция. Отсюда два следствия: разные группы читают один топик независимо и каждая со своей позиции, а внутри группы перезапуск экземпляра продолжает работу с закоммиченного места.
var config = new ConsumerConfig {
BootstrapServers = "kafka:9092",
GroupId = "billing-worker",
EnableAutoCommit = false
};
using var consumer = new ConsumerBuilder<string, string>(config).Build();
consumer.Subscribe("payments");
while (!token.IsCancellationRequested) {
var cr = consumer.Consume(token);
await Handle(cr.Message);
consumer.StoreOffset(cr);
}Добавьте про ребалансировку: при входе, выходе или зависании участника группа перераспределяет партиции, и обработка на это время встаёт.
Где спотыкаются
Обещают горизонтальное масштабирование добавлением реплик, забыв, что партиций фиксированное число. Увеличить их можно, уменьшить нельзя, а рост числа партиций ломает порядок для ключа, который переедет в другую партицию.
Оставляют автокоммит и считают доставку строго однократной. Автокоммит подтверждает смещение по таймеру, независимо от того, дошло ли сообщение до базы: падение между коммитом и записью теряет сообщение, обратный порядок даёт повтор. Обработчик обязан быть идемпотентным.
Держат долгую обработку прямо в цикле опроса и получают бесконечные ребалансировки: брокер считает участника мёртвым, если тот не вернулся за отведённое время, отдаёт партиции соседу, и та же работа выполняется дважды.