Что такое семантика доставки в Kafka и какие бывают типы
Что проверяют
Понимаете ли вы, что гарантия доставки это не один флаг, а свойство всей цепочки: продюсер, брокер, момент коммита оффсета и приёмник на выходе. Для Java-разработчика это ещё и вопрос о том, где в вашем коде живёт дедупликация, потому что чаще всего она живёт именно там.
Как отвечать
Семантик три. At most once: сообщение может потеряться, но не задвоится; со стороны потребителя это коммит оффсета до обработки, со стороны продюсера отказ от повторов. At least once: потерь нет, дубли возможны; коммит после обработки, повторы включены. Exactly once: эффект применяется однократно.
Дальше важно сказать, чем это включается. От потери защищает acks=all вместе с min.insync.replicas больше единицы. От дублей при повторах защищает идемпотентный продюсер: брокер отсеивает повторы по идентификатору продюсера и порядковому номеру внутри партиции. Полноценный exactly once это транзакции: свой transactional.id, атомарная запись сообщений вместе с оффсетами и read_committed у читателя.
Ключевую оговорку как раз и ждут: транзакции действуют внутри Kafka, то есть в сценарии прочитал, обработал, записал обратно. Как только сервис пишет в базу или дёргает чужой HTTP, гарантия кончается, и остаётся at least once плюс идемпотентный приёмник: ключ дедупликации, вставка с обновлением по бизнес-идентификатору, отдельная таблица исходящих сообщений.
Где спотыкаются
Считают, что exactly once означает единственную физическую доставку. Сеть всё равно повторяет, просто повторы отбрасываются по порядковому номеру и транзакционным маркерам. Обещать отсутствие повторов на проводе нельзя, речь только о результате.
Уверены, что acks=all уже спасает от дублей. Это защита от потери: при таймауте подтверждения продюсер отправит партию заново, и без идемпотентности в логе окажутся две записи одного сообщения.
Забывают про автокоммит оффсетов по таймеру. Он незаметно подменяет выбранную семантику: часть сообщений отмечается обработанной раньше, чем обработка закончилась, и при падении они теряются. Отсюда правило про ручной коммит после успеха.