Ответ
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) также требуется идемпотентность на уровне бизнес-логики приложения, так как дубликаты могут возникнуть из-за повторных попыток отправки продюсером или повторной обработки консьюмером после сбоя до фиксации смещения.