Как обрабатывать дубликаты сообщений
Что проверяют
Понимаете ли вы, что дубликаты это нормальное следствие гарантии at-least-once, а не редкий сбой. Интервьюер ждёт идемпотентного потребителя и того, как проверка на дубль сделана атомарной с самой обработкой. Следом спрашивают про exactly-once в Kafka и о том, что он покрывает на самом деле.
Как отвечать
Сначала откуда дубли: продюсер повторил отправку после таймаута, потребитель обработал сообщение, но упал до коммита offset, группа ушла в ребалансировку. Потом способы:
- естественная идемпотентность: операция безопасна при повторе.
SET status = 'PAID'можно выполнить дважды, аbalance = balance + 100нельзя; - ключ идемпотентности: у сообщения стабильный ID от отправителя, UUID события или бизнес-ключ вроде номера платежа. Генерировать новый ID на каждой попытке отправки бессмысленно;
- таблица обработанных:
processed_messages(message_id PRIMARY KEY). Вставка ID и бизнес-изменение идут в одной транзакции (@Transactionalв Spring), дубль ловится уникальным ограничением, напримерINSERT ... ON CONFLICT DO NOTHINGс проверкой числа вставленных строк; - порядок коммита: offset подтверждается только после успешной обработки. Spring Kafka по умолчанию так и делает, отключая
enable.auto.commit; - сторона продюсера:
enable.idempotence=true(в клиентах с Kafka 3.0 включено по умолчанию) убирает дубли от повторов внутри сессии продюсера, а transactional outbox закрывает случай «записали в базу, но не отправили».
Про exactly-once скажите честно: транзакции Kafka дают его для цепочки «прочитал из топика, записал в топик». Как только есть внешний побочный эффект (база, HTTP, письмо), нужна идемпотентность на вашей стороне.
Таблицу ID чистите по TTL или партициями по дате, окно хранения держите больше максимального времени повторной доставки.
Где спотыкаются
Хранят обработанные ID в HashSet в памяти. Он не потокобезопасен, теряется при рестарте и не виден другим инстансам.
Делают «проверил, обработал, записал ID» без транзакции и уникального ключа. Два параллельных потребителя проходят проверку одновременно.
Обещают exactly-once «из коробки», потому что включили идемпотентного продюсера.