Когда продюсер считает запись успешной и почему acks=1 при replication factor 3 всё равно теряет данные.
Параметр acks отвечает на один вопрос: в какой момент продюсер считает запись успешной.
acks=0 — не ждёт ничего. Отправил и забыл. Потери не будут даже замечены приложением, потому что никакой обратной связи нет. Допустимо только для метрик и телеметрии, где потеря части точек не меняет картину.
acks=1 — ждёт подтверждения от лидера партиции. Выглядит разумным компромиссом и именно поэтому опасен: между записью на лидера и репликацией на фолловеров есть окно. Если лидер умирает внутри этого окна, новый лидер выбирается из ISR с более коротким логом, и всё, что не успело реплицироваться, отрезается при truncate. Продюсер при этом уже получил подтверждение и ничего повторять не будет. Replication factor 3 от этого не спасает.
acks=all — ждёт, пока запись подтвердят все реплики из ISR. С Kafka 3.0 это значение по умолчанию (KIP-679), вместе с включённой по умолчанию идемпотентностью продюсера.
Ключевая тонкость: acks=all означает «все реплики из ISR», а не «все реплики вообще». Если ISR сжался до одного лидера, «все» — это он один, и гарантия исчезает. Поэтому acks=all работает только в связке с min.insync.replicas ≥ 2: тогда при нехватке синхронных реплик брокер отклонит запись вместо того, чтобы принять её в одиночку.
Рабочая формула для прода: replication.factor=3, min.insync.replicas=2, acks=all. Она переживает потерю одной ноды без потери данных и без остановки записи. Цена — при потере двух нод запись останавливается, и это бизнес-решение, которое стоит явно проговорить в требованиях.
Задержка вырастает на время репликации внутри кластера — обычно единицы миллисекунд. Пропускная способность почти не страдает, потому что записи идут пакетами.
Минимальное число синхронных реплик, при котором брокер соглашается принять запись с acks=all. При меньшем числе возвращается ошибка NOT_ENOUGH_REPLICAS.
Да. acks=all защищает от потерь, идемпотентность — от дублей, которые создаёт сам продюсер при повторной отправке после таймаута.