Вопрос 23 · Раздел 15

Что такое idempotent producer

4. Broker-side validation — защита от дубликатов на стороне брокера

Версии по языкам: English Russian Ukrainian

Уровень Junior

Определение

Idempotent producer — это продюсер, который гарантирует, что дубликаты не попадут в Kafka при retry.

props.put("enable.idempotence", "true");
// Автоматически устанавливает:
// acks=all
// retries=Integer.MAX_VALUE
// max.in.flight.requests.per.connection=5

Зачем нужен?

Без idempotence:
  Продюсер отправил → network error → retry → дубликат в Kafka

С idempotence:
  Продюсер отправил → network error → retry → брокер отклоняет дубликат

Как работает?

Каждый producer получает уникальный PID (Producer ID)
Каждое сообщение получает Sequence Number
Брокер отслеживает последовательность

Дубликат с тем же PID + Sequence → отклоняется

Уровень Middle

Когда НЕ использовать идемпотентный продюсер

  1. Совместимость со старыми брокерами (pre-0.11) — idempotence не поддерживается
  2. Ultra-low latency с допустимыми дубликатами — можно отключить для минимального overhead

Internal Mechanism

PID (Producer ID) — уникальный ID продюсера
Sequence Number — увеличивается для каждого сообщения
Брокер проверяет последовательность:
  - Если sequence = expected → записывает
  - Если sequence < expected → дубликат, отклоняет
  - Если sequence > expected → out of order, ошибка

Automatic Settings

enable.idempotence=true автоматически устанавливает:
  acks=all
  retries=Integer.MAX_VALUE
  max.in.flight.requests.per.connection=5 (начиная с Kafka 1.1, до этого было ограничение 1).

Не нужно настраивать вручную!

Transactional Producer

// Для exactly-once семантики
props.put("transactional.id", "my-tx-id");
props.put("enable.idempotence", "true");

producer.initTransactions();
producer.beginTransaction();
producer.send(record);
producer.commitTransaction();

Типичные ошибки

  1. Без idempotence при retries:
    Retry → дубликаты в топике
    → Обработка дважды
    
  2. Ручное изменение PID:
    PID генерируется автоматически
    Ручное изменение сломает механизм
    
  3. enable.idempotence=false с retries:
    Retries включены, idempotence выключена
    → Дубликаты при retry
    

Уровень Senior

Internal Implementation

PID Assignment:

При создании producer:
1. Producer → InitProducerId request → Broker
2. Broker → генерирует уникальный PID
3. Broker → возвращает PID + epoch
4. Producer → использует PID для всех сообщений

Sequence Number Management:

Каждый producer-partition pair имеет свой sequence number:
  Producer P1, Partition 0 → seq=0
  Producer P1, Partition 0 → seq=1
  Producer P1, Partition 1 → seq=0 (другая партиция)

Sequence number увеличивается на каждое сообщение

Broker Validation:

Брокер проверяет:
1. PID соответствует текущему producer
2. Sequence number = expected (не меньше)
3. Если sequence < expected → duplicate, reject
4. Если sequence > expected → out of order, error

Exactly-Once Semantics

Idempotent producer — основа exactly-once:
1. Producer: enable.idempotence=true
2. Producer: transactional.id (для transactions)
3. Consumer: isolation.level=read_committed

Только Kafka-to-Kafka сценарии!

Failure Scenarios

1. Producer Restart:

Producer restarts → новый PID
Старые sequence numbers не влияют
Новый producer начинает с sequence=0

2. Broker Failover:

Leader упал → новый лидер
Новый лидер знает последний sequence number
Продолжает validation с того же места

3. Network Partition:

Producer → отправил → network error → retry
Брокер получил → записал → ack потерян
Producer → retry → брокер видит дубликат → отклоняет

Performance Impact

Idempotent producer overhead:
  ~5-10% latency increase
  ~5% throughput decrease
  Минимальный CPU overhead

Trade-off: надёжность vs производительность

Monitoring

Ключевые метрики:

kafka.producer:produce-throttle-time-avg
kafka.producer:failed-authentication-rate
kafka.producer:idempotent-rate (если доступна)

Best Practices

✅ enable.idempotence=true по умолчанию (Kafka 3.0+); для старых версий нужно устанавливать явно.
✅ Для exactly-once — добавить transactional.id
✅ Без изменения настроек по умолчанию
✅ Мониторинг failed sends

❌ Без idempotence при retries
❌ Ручное изменение PID
❌ enable.idempotence=false с retries
❌ Без обработки ошибок отправки

Архитектурные решения

  1. Idempotence по умолчанию — минимальный overhead, максимальная надёжность
  2. Transactional ID для exactly-once — Kafka-to-Kafka сценарии
  3. Sequence numbers per partition — независимая валидация
  4. Broker-side validation — защита от дубликатов на стороне брокера

Резюме для Senior

  • Idempotent producer предотвращает дубликаты при retry
  • PID + Sequence Number — механизм дедупликации
  • Автоматически устанавливает acks=all и retries=INT_MAX
  • Exactly-once требует transactional.id
  • Minimal performance overhead, maximum reliability benefit

🎯 Шпаргалка для интервью

Обязательно знать:

  • Idempotent producer гарантирует: дубликаты не попадут в Kafka при retry
  • PID (Producer ID) + Sequence Number — механизм дедупликации на брокере
  • enable.idempotence=true автоматически ставит: acks=all, retries=INT_MAX, max.in.flight=5
  • Брокер проверяет sequence: если < expected → duplicate reject; если > → out of order error
  • Sequence number per partition — независимая валидация для каждой партиции
  • Для exactly-once: добавить transactional.id + Transaction API
  • Overhead: ~5-10% latency increase, ~5% throughput decrease — минимальный

Частые уточняющие вопросы:

  • Что будет без idempotence при retries? — Retry → дубликаты в топике → двойная обработка.
  • Генерируется ли PID вручную? — Нет, автоматически брокером при создании producer.
  • Как broker обрабатывает failover? — Новый лидер знает последний sequence number, продолжает validation.
  • enable.idempotence=false с retries — что будет? — Retries включены, дубликаты возможны.

Красные флаги (НЕ говорить):

  • «Idempotent producer можно отключить для production» — retries без idempotence = дубликаты
  • «PID можно настроить вручную» — генерируется автоматически брокером
  • «Idempotence защищает от дубликатов между разными producer» — только внутри одного producer
  • «Exactly-once работает без transactional.id» — нужен transactional.id для transactions

Связанные темы:

  • [[11. Как настроить exactly-once семантику]]
  • [[9. Какие гарантии доставки сообщений предоставляет Kafka]]
  • [[20. Что такое producer acknowledgment и какие режимы существуют (acks=0,1,all)]]
  • [[21. Что такое batch в Kafka producer]]