Гарантии доставки сообщений в Kafka✈️
В распределенных системах часто приходится выбирать: в каких сценариях можно позволить себе потерю или задержку сообщения, а где важно гарантировать его обработку без повторов.
В Kafka есть несколько уровней гарантий доставки: At Most Once, At Least Once и Exactly Once. От выбора уровня зависит поведение системы при сбоях, баланс между производительностью и надежностью, а также требования к идемпотентности обработки.
Предлагаю разобрать подробно, что означает каждая гарантия и где её целесообразно применять.
✅At Most Once (Не более одного раза) Это гарантия, при которой сообщение отправляется только один раз, и если оно потерялось, повторной доставки не будет. Такой подход исключает дублирование, но допускает потерю данных.
Как это работает в Kafka? ⭕️Продюсер отправляет сообщение, не дожидаясь подтверждения от брокера (acks=0). ⭕️Брокер не гарантирует сохранение, т.е. сообщение может быть потеряно при сбое. ⭕️Консьюмер может использовать автофиксацию смещений (enable.auto.commit=true), что приведет к автоматическому коммиту даже до успешной обработки данных.
Но! Если консьюмер упадет после чтения сообщения, но до завершения обработки, это сообщение уже не будет доступно для повторной обработки.
Когда использовать? Подходит для систем, где допустима небольшая потеря данных ради высокой пропускной способности, например: ⭕️сбор событий кликов на веб-сайтах; ⭕️телеметрия с IoT-устройств, где пропуски некритичны.
✅At Least Once (Как минимум один раз) Гарантирует, что сообщение будет доставлено минимум один раз. Это исключает потерю сообщений, но допускает их дублирование.
Как это работает в Kafka? ⭕️Продюсер отправляет сообщение и ждет подтверждения от брокера (acks=1 или acks=all). ⭕️Консьюмер получает сообщение, обрабатывает его и только после успешной обработки коммитит смещение (manual commit). ⭕️Если консьюмер или процесс обработки упадет после выполнения бизнес-логики, но до комитта, консьюмер сможет запросить то же сообщение повторно.
Чтобы избежать искажений при повторной обработке, операции должны быть идемпотентными, т.е. повторное выполнение не должно изменять результат.
Когда использовать? Подходит для систем, где потеря данных недопустима, а дублирование можно обработать: ⭕️обработка заказов или событий e-commerce; ⭕️системы мониторинга и логирования; ⭕️ETL-пайплайны, где данные могут быть дедуплицированы на следующем шаге.
✅Exactly Once (Ровно один раз) Строгая гарантия, при которой сообщение обрабатывается ровно один раз, даже при сбоях или повторных доставках.
Как это работает в Kafka? ⭕️Продюсер включает идемпотентность (enable.idempotence=true), чтобы брокер игнорировал дубликаты сообщений. ⭕️Используются транзакции, объединяющие запись сообщений и фиксацию смещений в одну атомарную операцию. ⭕️После успешной транзакции коммит смещений и запись данных происходят одновременно, что исключает двойную обработку.
Консьюмер должен использовать isolation.level=readcommitted, чтобы видеть только зафиксированные транзакции.
**Когда использовать? **Идеален для критичных сценариев, где недопустимы ни потери, ни дублирование: ⭕️финансовые расчеты и платежные системы; ⭕️обработка заказов с жесткими гарантиями; ⭕️интеграции, где консистентность данных обязательна.
Зафиксируемся: ⭕️At Most Once - высокая скорость, но есть риск потери данных. ⭕️At Least Once - надежно, но возможны дубликаты. ⭕️Exactly Once - идеальная консистентность, но требует дополнительных усилий и ресурсов.
Источники: 📎Доставка сообщений и гарантии Kafka 📎Гарантированная доставка и хранение данных в Apache Kafka: внутренняя механика
©️что-то на инженерном