Как в Kafka обеспечиваются гарантии доставки сообщений?

Ответ

Гарантии доставки в Kafka — это не место хранения, а режим работы, который настраивается в основном на стороне продюсера (Producer) с помощью параметра acks.

Существует три основных уровня гарантий:

  1. At most once (Не более одного раза): acks=0

    • Продюсер отправляет сообщение и не ждет подтверждения от брокера.
    • Риски: Высокая производительность, но возможна потеря сообщений (например, если брокер упал в момент получения).
  2. At least once (Как минимум один раз): acks=1 (значение по умолчанию)

    • Продюсер ждет подтверждения только от лидера партиции. Если лидер подтвердил запись, но упал до того, как реплики скопировали данные, может быть выбран новый лидер, и продюсер повторит отправку.
    • Риски: Сообщения не теряются, но могут возникать дубликаты при повторных отправках.
  3. 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