Подтверждения (acks) и идемпотентный продюсер
Урок про надёжность записи: сколько подтверждений ждать и как не насоздавать дубликатов при повторах.
acks — настройка продюсера, задающая, сколько реплик должны подтвердить запись, прежде чем она считается успешной; идемпотентный продюсер гарантирует, что повтор отправки не создаст дубликат.
Зачем это нужно
Сеть ненадёжна: ответ брокера может потеряться, и продюсер повторит отправку — а сообщение, возможно, уже записано. Без защиты это даёт дубликаты. А параметр acks определяет, насколько вы уверены, что запись вообще переживёт сбой брокера. Это два ключевых рычага надёжности на стороне записи.
Уровни acks
| acks | Ждём подтверждения от | Риск |
0 | никого (выстрелил и забыл) | потеря данных, максимум скорость |
1 | только лидера | потеря, если лидер упал до репликации |
all (-1) | лидера и всех ISR-реплик | надёжно, чуть выше задержка |
Для важных данных — acks=all: запись подтверждена, только когда её получили все синхронные реплики, и падение одного брокера её не теряет.
Проблема дубликатов при ретрае
Продюсер -> [записать M] -> Брокер: записал M (off 5) Брокер -> ack ...X (ack потерялся в сети) Продюсер: "ответа нет" -> повтор [записать M] Брокер: записал M снова (off 6) -- ДУБЛЬ!
Идемпотентный продюсер
Включение enable.idempotence=true решает это. Продюсер получает уникальный producer id и нумерует сообщения порядковыми номерами на партицию. Брокер запоминает последний принятый номер и отбрасывает повтор с уже виденным номером — запись произойдёт ровно один раз, несмотря на ретраи.
# надёжный продюсер без дублей
acks=all
enable.idempotence=true
retries=2147483647
max.in.flight.requests.per.connection=5
Как работает под капотом
При идемпотентности каждое сообщение несёт пару (producer id, sequence number) на партицию. Брокер хранит последний записанный sequence для этой пары; если приходит сообщение с номером, который уже записан (ретрай), брокер отвечает «ок», но повторно не пишет — дубль не попадает в лог. Номера строго возрастают, поэтому брокер также ловит «дыры» (пропуск номера) и сигнализирует об ошибке. Идемпотентность работает в пределах одной сессии продюсера и одной партиции; межпартиционные и кросс-сессионные гарантии даёт уже транзакционный продюсер (основа exactly-once).
Частые ошибки
- acks=1 для критичных данных. Если лидер упал до репликации, подтверждённая запись теряется.
- Ретраи без идемпотентности. Повторы при потерянных ack плодят дубликаты в логе.
- acks=0 «ради скорости». Это режим без гарантий: часть событий молча пропадёт под нагрузкой.
Итоги
acksзадаёт надёжность записи:0— быстро и без гарантий,all— переживает падение брокера.- Ретраи без защиты создают дубликаты; идемпотентный продюсер их устраняет нумерацией сообщений.
- Надёжный профиль:
acks=all+enable.idempotence=true.