Гарантирована ли доставка сообщения в Kafka?

Ответ

Kafka обеспечивает at-least-once доставку сообщений по умолчанию, но не гарантирует exactly-once без дополнительной настройки.

Нюансы acks (подтверждений от брокеров):

  • Если acks=all (или -1), продюсер ждёт подтверждения от всех реплик (лидера и фолловеров) перед подтверждением записи. Это обеспечивает высокую надёжность, но может замедлить запись.
  • При acks=1 (лидер) продюсер ждёт подтверждения только от лидера партиции. Возможна потеря данных при сбое лидера до репликации на фолловеров.
  • При acks=0 (нет подтверждения) продюсер не ждёт подтверждения от брокера. Это самая быстрая, но наименее надёжная опция, возможны потери сообщений.

Пример настройки продюсера (Go, Sarama):

config := sarama.NewConfig()
config.Producer.RequiredAcks = sarama.WaitForAll // Ждём подтверждения от всех реплик
config.Producer.Return.Successes = true          // Важно для получения подтверждений

Для exactly-once (на уровне Kafka):

  • Идемпотентность продюсера: Используйте enable.idempotence=true. Это гарантирует, что повторные попытки отправки одного и того же сообщения продюсером будут записаны в лог Kafka ровно один раз, предотвращая дубликаты на стороне брокера.
  • Транзакции: Используйте Producer.Transactional.ID. Транзакции позволяют атомарно отправлять несколько сообщений в разные топики/партиции и атомарно фиксировать смещения консьюмера. Это обеспечивает exactly-once обработку сообщений консьюмером (при правильной настройке).

Важно: exactly-once в Kafka гарантирует, что сообщение будет записано в лог ровно один раз и обработано консьюмером ровно один раз (при использовании транзакций). Для сквозной exactly-once доставки (end-to-end) также требуется идемпотентность на уровне бизнес-логики приложения, так как дубликаты могут возникнуть из-за повторных попыток отправки продюсером или повторной обработки консьюмером после сбоя до фиксации смещения.