Гарантии доставки

Версия 1.10 от Alexandr Fokin на 2026/07/19 13:20

Материалы
 Apache Kafka в гарантиях или как надежно доставить сообщение
https://habr.com/ru/companies/otus/articles/930372/
 Kafka для начинающих: Гарантии доставки на практике и идемпотентность
https://habr.com/ru/articles/961048/
  
 
ТипОписаниеProducerConsumer

At‑Most‑Once

Гарантия доставки не более одного раза.
Гарантируется, то не будет дублей, но допускаются потери.
Без подтверждения доставки и повторных отправок (гарантирует отсутствие дублей), но сообщение может быть потеряно на фазе отправки (т.к. без подтверждения).

Acks = None
MessageSendMaxRetries = 0
Сообщение коммитится сразу (без подтверждения), это гарантирует что не будет дублирования, но сообщение может быть потеряно на фазе получения (падение или timeout потребителя).

AutoOffsetReset = AutoOffsetReset.Earliest
ENABLE_AUTO_COMMIT = true

At‑Most‑Once

Гарантия доставки хотя бы один раз.
Гарантируется, что не будет потерь, но возможны дубли.
1) Гарантия подтверждения доставки до про брокера.
В данном случае отправка может выполнится, но потеряется подтверждение отправки. В таком случае будет повторная отправка, которая приведет к дублированию на отправке.

Acks = All
EnableIdempotence = false

2) Дополнение. Наличие функции дедубликации в kafka.
Позволяет устранить дублирование на отправке. Kafka отслеживает повторную отправку и отбрасывает.

EnableIdempotence = true
MessageSendMaxRetries <> 0

transactional.id - влияет на идентификацию экземпляра producer при переподключении. 
Использование ручного коммита после завершения обработки (транзакции БД).

AutoOffsetReset = AutoOffsetReset.Earliest
ENABLE_AUTO_COMMIT = false

Может использоваться для дедупликации.
TransactionalInbox.

Падение consumer или отвал по timeout (долгая обработка)  может привести к отключению consumer по timeout. Это может провести к тому, что сообщение поступит на другой потребитель. В таком случае только TransactionalInbox.

Exactly‑Once

Гарантия доставки строго один раз.
Гарантия отсутствия потерь и дублей.
Kafka transactions 
 
TransactionalInbox
ПолныйХранится IdempotencyId каждого входящего сообщения (уникальный индекс), для дедубликации.
Полная защита от дублей (даже если это несколько сообщений, с одинаковым ключом).
Только offset (облегченный)Специфично для kafka. Храниться только topic+partition+offset.
Защищает только от потери смещения (сообщение обработано, но offset не закомичен) и consumer timeout. Не поможет при дублировании на отправке (более 1 сообщения).
  
  
 Более строгие гарантии могут давать большие накладные расходы (пропускная способность и задержка доставки).