null

Коммиты сообщений в Apache Kafka

Начало

Данная статья предназначена для тех, кто уже работал или ознакомлен с основами Apache Kafka. При создании сервисов или микросервисов, зачастую требуется использовать брокер сообщений как средство коммуникации между сервисами. Apache Kafka является серьезным решением, с огромным количеством возможностей и настроек. Сегодня мы разберемся, как на самом деле работают Consumer'ы в Kafka, их возможности и неочевидные моменты, а также как работают коммиты сообщений.

Стратегия запросов

Apache Kafka является не совсем классическим брокером сообщений. Проявляется это во многих моментах, однако на данный момент нас интересует стратегия запросов для получения новых сообщений. Различают две стратегии: push и pull. Стратегия push используется в классических брокерах по типу RabbitMQ и подразумевает, что сервер делает запрос к клиенту, отправляя ему новые данные. Стратегия pull в свою очередь используется в Apache Kafka и работает так, что консьюмеры сами, раз в определенное количество секунд отправляют запрос на сервер для получения новых данных. 

Коммиты сообщений

Для начала стоит разобраться в устройстве и организации консьюмеров Apache Kafka. Существует понятие группы, в которые объединяются эти самые консьюмеры. Для каждой группы существует собственное смещение (offset) относительно каждой партиции каждого топика. Благодаря этому можно поддерживать консистентность данных, ведь сообщения, которые обработал один консьюмер из группы уже не попадут к другому. Поддерживается это с помощью коммитов сообщений, которые сохраняются в отдельном топике __consumer_offsets в определенном формате, включающем в себя топик, партицию, группу консьюмеров, а также смещение.

 

Теперь стоит поговорить насчет ack mode и семантику доставки сообщений. Разделяют 3 семантики и связи между ack mode:

  • at most once - ack mode не задан (auto commit)
  • at least once - manual ack mode (manual commit)
  • exactly once - написана своя логика, которая не полагается на Kafka offset

Теперь рассмотрим подробнее. Когда у нас не задан ack mode, то при получении новых данных, консьюмер сразу коммитит сообщение при получении. С этим могут возникнуть проблемы, ведь сообщение может быть каким-то образом обработано, что может вызвать ошибку, вследствие чего сообщение просто потеряется. В ситуации с manual ack mode может возникнуть другая проблема, когда был получен батч сообщений и одно из них вызвало ошибку. В таком случае консьюмер снова попытается получить этот батч и сообщения в нем, которые были обработаны до сообщения с ошибкой будут получены и обработы снова, что подразумевает дублирование сообщений. В таком случае, если очередь сообщений не идемпотентна (отслеживание изменений имени пользователя), то могут возникнуть различные проблемы. Если того требует бизнес задача, чтобы таких проблем не возникало, стоит написать свою систему управления смещениями, которая будет сохранять в нужное место смещение сообщения, которое удалось успешно обработать.

Также в Kafka есть настройка auto.offset.reset, которая принимает 2 значения: earliest и latest и отвечает за то, с какого смещения считывать сообщения новым группам консьюмеров. Это может пригодиться, если нужно, чтобы приложение всегда считывало очередь сначала. Главное не забывать, что это касается только новых групп. 

Заключение

Apache Kafka является мощным, быстрым и надежным брокером сообщений, которым пользуются корпорации каждый день. На сегодня мой рассказ окончен, мы разобрали, как работают коммиты сообщений в Apache Kafka и чуть более детально погрузились в устройство Kafka Consumer. Надеюсь моя статья была вам полезна и возможно даже помогла, спасибо за внимание!

 

Вперед