Найти в Дзене
Crazy Coder

Гарантии доставки в Kafka. Как не терять сообщения

ACK (acknowledgment) — подтверждение от Kafka брокера, что сообщение успешно получено и записано. Kafka поддерживает 3 уровня подтверждения: 0 - Продюсер не ждёт подтверждения (возможна потеря сообщений). 1 - Брокер-лидер партиции подтверждает получение.
all / -1 - Сообщение считается принятым, когда все ISR (in-sync replicas) подтвердят запись. Это наиболее надежный вариант. goКопироватьРедактироватьw := kafka.NewWriter(kafka.WriterConfig{
Brokers: []string{"localhost:9092"},
Topic: "example-topic",
RequiredAcks: kafka.RequireAll, // можно kafka.RequireOne или kafka.RequireNone
}) At most once - Сообщения могут потеряться, но не будут дублироваться. At least once - Сообщения не потеряются, но могут дублироваться. Exactly once - Сообщения не теряются и не дублируются. Самая сложная реализация. Kafka по умолчанию предоставляет at least once гарантию. Тут всё зависит от роли: goКопироватьРедактироватьw := kafka.NewWriter(kafka.WriterConfig{
Brokers: []str
Оглавление

✅ Что такое ACK в Kafka?

ACK (acknowledgment) — подтверждение от Kafka брокера, что сообщение успешно получено и записано.

Kafka поддерживает 3 уровня подтверждения:

0 - Продюсер не ждёт подтверждения (возможна потеря сообщений).

1 - Брокер-лидер партиции подтверждает получение.
all / -1 - Сообщение считается принятым,
когда все ISR (in-sync replicas) подтвердят запись. Это наиболее надежный вариант.

✍️ Как задать acks в Go (с использованием segmentio/kafka-go):

goКопироватьРедактироватьw := kafka.NewWriter(kafka.WriterConfig{
Brokers: []string{"localhost:9092"},
Topic: "example-topic",
RequiredAcks: kafka.RequireAll, // можно kafka.RequireOne или kafka.RequireNone
})

📦 Какие гарантии доставки есть в Kafka?

At most once - Сообщения могут потеряться, но не будут дублироваться.

At least once - Сообщения не потеряются, но могут дублироваться.

Exactly once - Сообщения не теряются и не дублируются. Самая сложная реализация.

📌 По умолчанию:

Kafka по умолчанию предоставляет at least once гарантию.

🎯 Как добиться exactly-once доставки?

Тут всё зависит от роли:

✅ Для продюсера:

  • Включи идемпотентность (idempotent producer).
  • Используй acks=all и повторы включены (retries > 0).

goКопироватьРедактироватьw := kafka.NewWriter(kafka.WriterConfig{
Brokers: []string{"localhost:9092"},
Topic: "example-topic",
RequiredAcks: kafka.RequireAll,
Async: false, // важно для контроля ошибок
MaxAttempts: 3, // повторы
// Важно: в segmentio/kafka-go нет прямой поддержки идемпотентности,
// для полного exactly-once уровня лучше использовать Confluent Kafka client.
})

Для полного Exactly Once Semantics (EOS) лучше использовать клиент от Confluent, так как segmentio/kafka-go не поддерживает transactions/idempotent producer на 100%.

✅ Для консюмера:

  • Использовать идемпотентную логику обработки (или транзакции).
  • Коммитить offset только после успешной обработки.

goКопироватьРедактироватьm, err := r.ReadMessage(ctx)
// Обработка
if err := processMessage(m); err == nil {
// Kafka-go автоматически коммитит offset если AutoCommit = true
} else {
// Обработка ошибки, offset не коммитим
}

🧪 Exactly-once обработка (общая стратегия)

Kafka поддерживает транзакции у продюсеров и атомарные коммиты вместе с offset'ами. Но это есть только в:

  • Confluent Kafka Go client
  • С помощью API InitTransactions, BeginTransaction, SendOffsetsToTransaction, CommitTransaction.

В segmentio/kafka-go пока нет встроенной поддержки транзакций.

🔐 Кратко:

Надежная запись acks=all, retries > 0

Без дубликатов - Включить идемпотентность

Exactly once - Использовать транзакции (через Confluent Kafka client)