Гайды

Dead Letter Queue и обработка ошибок в Kafka

Poison message, топик DLQ и коммиты, retry-цепочки, заголовки, идемпотентность, Connect errors.tolerance и антипаттерны.

~9 мин чтения

Dead Letter Queue и обработка ошибок в Kafka

В Kafka нет встроенной DLQ как в RabbitMQ — паттерн строится топиками и логикой consumer'а. Цель — не застревать на poison message и не терять контекст отладки. Consumer semantics — Kafka Consumers и consumer groups; Connect — Kafka Connect.

Если consumer долго не вызывает poll(), брокер исключит его из группы (max.poll.interval.ms); при обработке «тяжёлой» записи комбинируйте pause/resume партиции или увеличьте интервал осознанно, иначе получите дубли и лавину ребалансов.


1. Poison message

Сообщение, которое всегда падает при обработке (битый JSON, баг кода, несовместимая схема). Без DLQ consumer будет бесконечно получать его (at-least-once) и блокировать прогресс партиции.


2. Паттерн: основной топик + DLQ

  1. Обработать батч из poll().
  2. На per-record ошибке:
    • записать оригинал + метаданные (stack, offset, partition) в orders.dlq;
    • закоммитить offset основного топика (или коммитить до проблемной записи — зависит от стратегии).

Варианты:

  • Пропуск с коммитом после записи в DLQ — прогресс идёт; риск потери если DLQ-write упал до commit (нужна транзакция или outbox).
  • Пауза партиции и алерт — если любая потеря недопустима.

3. Транзакции read-process-write

Transactional consumer + producer — отправка в DLQ и commit offset'ов в одной транзакции (EOS в пределах поддерживаемой модели). Сложность выше; задержка выше.


4. Retry топик

Цепочка orders.retry.1m, orders.retry.10m с задержкой (через отдельный scheduler или Kafka Streams / tiered delay) отделяет временные ошибки от постоянных (после N попыток → DLQ).


5. Заголовки и envelope

В DLQ кладите headers: x-original-topic, x-error-class, x-retry-count. Значение — envelope (Avro/JSON) с телом и причиной. Схемы — Avro и Schema Registry.


6. Идемпотентность

DLQ-consumer при повторной обработке не должен дублировать side-effects в БД. Используйте ключ идемпотентности (business id) в таблице обработанных событий.


7. Kafka Connect

errors.tolerance=all + errors.deadletterqueue.topic.name — стандартный путь для connector tasks. Мониторьте рост DLQ. Подробнее — раздел в гайде по Connect.


8. Антипаттерны

АнтипаттернПочему плохо
Бесконечный retry без backoffDDOS собственной БД
Коммит до успешной обработкиПотеря сообщений
DLQ без мониторингаТихая деградация бизнеса
Один глобальный DLQ без типизацииНевозможно роутить на владельцев

9. Алерты и SLO

Алерт на рост lag основного топика + одновременный рост DLQ — признак массового бага релиза. Отдельный алерт на stale consumer (нет коммитов). SLO: время от первой ошибки до появления записи в DLQ с полным контекстом.


10. Replay и инструменты

kafka-console-consumer / отдельный replay job читает DLQ и публикует в исправленный топик или вызывает API с идемпотентностью. Версионируйте схему envelope, чтобы старые сообщения в DLQ оставались читаемыми.


11. Чек-лист

  • Явная политика: retry count, backoff, DLQ.
  • Мониторинг размера и rate DLQ.
  • Runbook: кто и как replays из DLQ после фикса.
  • Идемпотентность downstream.
  • TTL на DLQ-топик или архив в объектное хранилище, чтобы не забить кластер.

Дальше: Мониторинг Kafka · Тег Kafka