Ответ
Гарантии доставки в Kafka — это не место хранения, а режим работы, который настраивается в основном на стороне продюсера (Producer) с помощью параметра acks
.
Существует три основных уровня гарантий:
At most once (Не более одного раза):
acks=0
- Продюсер отправляет сообщение и не ждет подтверждения от брокера.
- Риски: Высокая производительность, но возможна потеря сообщений (например, если брокер упал в момент получения).
At least once (Как минимум один раз):
acks=1
(значение по умолчанию)- Продюсер ждет подтверждения только от лидера партиции. Если лидер подтвердил запись, но упал до того, как реплики скопировали данные, может быть выбран новый лидер, и продюсер повторит отправку.
- Риски: Сообщения не теряются, но могут возникать дубликаты при повторных отправках.
Exactly once (Строго один раз):
acks=all
(или-1
)- Продюсер ждет подтверждения от лидера и всех синхронизированных реплик (In-Sync Replicas, ISR). Это самая надежная гарантия со стороны брокера.
- Для достижения полной гарантии "строго один раз" также необходимо:
- На брокере установить
min.insync.replicas
(например, в 2), чтобы гарантировать запись минимум на N реплик. - На продюсере включить идемпотентность (
enable.idempotence=true
), что защищает от дублей при повторных отправках в рамках одной сессии. - Для атомарной записи в несколько партиций использовать транзакции.
- На брокере установить
Пример настройки продюсера на Go (библиотека Sarama):
config := sarama.NewConfig()
// Для гарантии "At least once" (по умолчанию)
// config.Producer.RequiredAcks = sarama.WaitForLocal
// Для гарантии "Exactly once" (самая строгая)
config.Producer.RequiredAcks = sarama.WaitForAll // Устанавливаем acks=all
config.Producer.Idempotent = true // Включаем идемпотентность
config.Net.MaxOpenRequests = 1 // Обязательно для идемпотентности
config.Producer.Return.Successes = true