Какие гарантии доставки сообщений предоставляет Kafka для консюмера
Что проверяют
Понимаете ли вы, что гарантия зависит от момента фиксации смещения, и знаете ли, чем платит каждый вариант.
Как отвечать
Три уровня, и выбирает их фактически сам потребитель тем, когда фиксирует смещение.
- не более одного раза: смещение фиксируется до обработки. Упали после фиксации, но до обработки, значит сообщение потеряно. Годится там, где потеря дешевле дубля;
- хотя бы один раз: смещение фиксируется после успешной обработки. Ничего не теряется, но при падении между обработкой и фиксацией сообщение придёт повторно. Это поведение по умолчанию и самое частое на практике;
- ровно один раз: достигается транзакциями Kafka (
isolation.level=read_committed, транзакционный производитель) и работает в пределах Kafka, то есть для сценария «прочитал, обработал, записал обратно в Kafka». Как только в цепочке появляется внешняя система, гарантия снова становится «хотя бы один раз».
Отсюда практический вывод, который и хотят услышать: раз в реальной системе почти всегда «хотя бы один раз», обработчик обязан быть идемпотентным. Ключ идемпотентности, проверка по идентификатору сообщения, ON CONFLICT DO NOTHING при записи.
Что ещё влияет: автоматическая фиксация по таймеру (enable.auto.commit) незаметно даёт «не более одного раза» при неудачной обработке, поэтому её отключают; долгая обработка дольше max.poll.interval.ms приводит к исключению потребителя из группы и перебалансировке, после которой сообщения приходят заново.
Где спотыкаются
Обещают «ровно один раз» без оговорок про внешние системы.
Оставляют автоматическую фиксацию и теряют сообщения при ошибках.
Не делают обработчик идемпотентным.
Не знают про перебалансировку и удивляются повторной обработке пачки.