Потеряет ли консьюмер Kafka сообщения при повторном подключении?
Что проверяют
Понимаете ли вы, что в Kafka означает «сообщение прочитано», и отличаете ли потерю от дубля. Для тестировщика вопрос сугубо практический: такие дефекты не видны на счастливом пути, их надо уметь воспроизвести и проверить.
Как отвечать
Сам по себе реконнект сообщений не теряет. Консьюмер продолжит с закоммиченного смещения, а смещения хранятся на брокере в служебном топике, а не в памяти приложения. Потеря появляется в двух случаях:
- смещение зафиксировано раньше, чем сообщение обработано. Автокоммит (
enable.auto.commit) фиксирует позицию последнего опроса по таймеру, поэтому падение между получением пачки и её обработкой съедает пачку целиком; - смещение уехало за пределы хранения: сегменты удалены по retention, а
auto.offset.resetвыставлен вlatest, и консьюмер перескакивает в конец топика, пропустив всё накопившееся.
Обратный режим, ручная фиксация после обработки, даёт дубли при падении, но не потерю. Это и есть доставка «хотя бы один раз», и правильный вывод не в том, чтобы добиться ровно одной доставки, а в том, чтобы обработчик был идемпотентным.
Что проверять: убить консьюмера в момент обработки, поднять и сверить обработанные идентификаторы на пропуски и повторы; отдельно поднять второй экземпляр в той же группе и повторить проверку на ребалансе.
Где спотыкаются
Отвечают, что Kafka гарантирует доставку, значит потерять ничего нельзя. Гарантии брокера про сохранность записанного в лог, а теряет сообщение код консьюмера, который сдвинул смещение вперёд раньше, чем довёл работу до конца.
Второе: считают, что режим «ровно один раз» включается флагом. Транзакции закрывают связку «прочитал из топика, обработал, записал в топик», но отправленное письмо, списание в платёжном шлюзе или запись во внешнюю базу они не откатят, и идемпотентность всё равно придётся делать руками.
Третье: проверяют только счётчик. Сошлось количество, значит всё хорошо. Одно потерянное и одно задвоенное сообщение дают ровно то же число, поэтому сверять надо множества ключей, а не их размер.