Всем привет, сегодня поговорим о гарантии Кафка, точнее о гарантии…

Всем привет, сегодня поговорим о гарантии Кафка, точнее о гарантии получения, ведь отправил в Кафку» не означает «получатель это обработал». Гарантия доставки — это не магическая настройка `acks=all`, а целая архитектура.

Если вы пишете на Java и используете Kafka, вот четыре уровня проверки того, что ваши события не потерялись и не размножились.

### 1. Уровень брокера: Идемпотентный продюсер (At-least-once без дублей)
Самый частый сценарий: сеть моргнула, продюсер сделал `retry`, и в топик улетело два одинаковых события.
* **Как проверить:** Включите `enable.idempotence=true`.
* **Как это работает:** Брокер присваивает продюсеру уникальный ID (PID) и следит за порядковым номером (sequence number) каждого сообщения в партиции. Если прилетает дубль с тем же sequence, брокер молча его отбрасывает.
* **Ограничение:** Это работает только внутри одной партиции. Если вы пишете в два разных топика, идемпотентность не спасет от частичной записи (в один топик записалось, в другой — нет).

### 2. Уровень приложения: Транзакционный продюсер (Exactly-once внутри Kafka)
Чтобы атомарно записать данные сразу в несколько партиций или топиков (и обновить смещения потребителя), нужны транзакции.
* **Как проверить:** Проверьте наличие `transactional.id`. Без уникального ID транзакции не работают.
* **Критические настройки Java/Spring:**
* `enable.idempotence=true` (обязательно).
* `max.in.flight.requests.per.connection=5` (иначе Kafka выбросит ошибку, так как пакеты могут обгонять друг друга).
* `isolation.level=read_committed` у потребителя. Если оставить `read_uncommitted`, потребитель прочитает «грязные» данные из незавершенной транзакции, которые потом исчезнут.
* **Spring Boot:** Используйте `@Transactional("kafkaTransactionManager")`. Это обернет отправку в Kafka и (при правильной настройке) работу с БД в единый контур.

### 3. Уровень бизнес-логики: Паттерн Transactional Outbox (End-to-End)
Главная проблема: Kafka не может участвовать в транзакции вашей базы данных (например, PostgreSQL). Если вы сначала сохранили заказ в БД, а потом отправили событие в Kafka, и приложение упало между этими шагами — у вас «фантомное событие» (или потерянное).
* **Как убедиться:** Используйте Outbox.
* **Схема:** Вы сохраняете и заказ, и событие в таблицу `outbox_events` в рамках одной SQL-транзакции. Отдельный фоновый процесс (Publisher) читает эту таблицу и шлет данные в Kafka.
* **Проверка:** Событие считается «долетевшим» только тогда, когда Publisher успешно записал его в Kafka и поставил в БД статус `PUBLISHED`.

### 4. Уровень мониторинга: Как убедиться, что всё живо
Настроить код — это половина дела. Убедиться, что он работает в проде — вторая.
* **Метрики продюсера:** Следите за `record-error-rate` и `transaction-aborted-rate`. Если транзакции часто откатываются (abort), значит, ваш батч слишком велик или обработка падает по таймауту.
* **Метрики потребителя (LSO lag):** При использовании `read_committed` обычный лаг (смещение от High Watermark) врет. Нужно смотреть на **LSO (Last Stable Offset) lag**. Если транзакция висит открытой 5 минут, потребитель будет стоять на месте, хотя в топике уже гигабайты новых данных.
* **Дедупликация на стороне базы:** Даже с идеальным EOS в Kafka, при записи в БД (например, через Sink Connector) используйте `INSERT ... ON CONFLICT`. Ключом дедупликации должен быть составной ID: `{topic}-{partition}-{offset}`.

**Чек-лист для Java-разработчика:**
1. `enable.idempotence=true` — всегда.
2. `transactional.id` — если пишете в несколько партиций.
3. `isolation.level=read_committed` — у всех критичных потребителей.
4. `max.in.flight.requests.per.connection <= 5` — иначе Kafka сбросит идемпотентность.
5. Outbox — если нужно связать БД и Kafka.
Просмотры: 7
Открыть в MAX Сообщить о неточности

Репосты публикации

Публикация канала

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти