Питання 14 · Розділ 15

У чому різниця між auto commit і manual commit

KafkaConsumer client автоматично надсилає commit request кожні auto.commit.interval.ms. Це client-side logic, не broker-side — брокер не ініціює комміт.

Мовні версії: English Russian Ukrainian

Рівень Junior

Auto Commit

KafkaConsumer client автоматично надсилає commit request кожні auto.commit.interval.ms. Це client-side logic, не broker-side — брокер не ініціює комміт.

props.put("enable.auto.commit", "true");
props.put("auto.commit.interval.ms", "5000");  // кожні 5 секунд

Плюси:

  • Просто, не потрібно викликати вручну
  • Kafka сама дбає про комміти

Мінуси:

  • Можливі втрати або дублікати
  • Коммітить навіть якщо не оброблено

Manual Commit

Ви самі вирішуєте коли зберегти offset.

props.put("enable.auto.commit", "false");
consumer.commitSync();  // коли хочете

Плюси:

  • Повний контроль
  • Комміт після обробки

Мінуси:

  • Потрібно викликати вручну
  • Більше коду

Порівняння

// Auto commit — просто
props.put("enable.auto.commit", "true");
consumer.subscribe(List.of("orders"));
// Kafka сама коммітить кожні 5 секунд

// Manual commit — надійно
props.put("enable.auto.commit", "false");
while (running) {
    ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
    for (var record : records) {
        process(record);
    }
    consumer.commitSync();  // після обробки
}

Рівень Middle

Auto Commit — деталі

Як працює:
1. Consumer poll → Kafka автоматично коммітить
2. Кожні auto.commit.interval.ms
3. Коммітить останній отриманий offset (не оброблений!)

Проблеми:
- Коммітить до обробки → втрата при падінні
- Фіксований інтервал → не залежить від обробки
- Немає контролю над помилками

Manual Commit — варіанти

Sync Commit:

// Чекає підтвердження від брокера
consumer.commitSync();
// Надійно, але повільніше

Async Commit:

// Не чекає підтвердження
consumer.commitAsync((offsets, exception) -> {
    if (exception != null) {
        log.error("Commit failed", exception);
    }
});
// Async commit надіслав request і не чекає. Якщо брокер впав до запису — offset не збережений.
// При перезапуску консьюмер прочитає ті самі повідомлення знову (дублікати, не втрата даних).

Типові помилки

  1. Auto commit + довга обробка:
    Комміт кожні 5 сек → обробка 10 сек → втрата повідомлень
    
  2. Manual commit без обробки помилок:
    consumer.commitAsync();  // помилка → ніхто не дізнається
    
  3. Mixed commit strategies:
    // Авто і ручний комміт одночасно
    // → Непередбачувана поведінка
    

When to Use What

Стратегія Коли використовувати
Auto commit Прототипи, тести, не-critical data
Manual sync commit Production, critical data
Manual async commit High-throughput, tolerant to duplicates

Рівень Senior

Internal Implementation

Auto Commit:

Реалізований в KafkaConsumer:
- При кожному poll() перевіряє чи минув інтервал
- Якщо так → надсилає commit request
- Не чекає відповіді (fire and forget)

Manual Commit:

commitSync():
  - Надсилає request → чекає response
  - Retry при transient errors
  - Викидає виключення при failure

commitAsync():
  - Надсилає request → не чекає
  - Callback при completion
  - No retry (caller responsibility)

Auto Commit Problems — Deep Dive

1. Offset Lag:

Auto commit коммітить отриманий offset, не оброблений

Timeline:
  T=0: Poll отримав offset 100
  T=2: Auto commit offset 100
  T=5: Почав обробку offset 100
  T=8: Впав

Результат: offset 100 втрачений (закоммічений, не оброблений)

2. Commit Interval Mismatch:

Швидка обробка + довгий commit interval:
  Обробив 1000 повідомлень → чекає 5 секунд → комміт
  Якщо впав → обробить 1000 повідомлень знову

Повільна обробка + короткий commit interval:
  Коммітить необроблені offsets → втрата даних

Production Patterns

1. Manual Sync Commit після батча:

while (running) {
    ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
    try {
        for (var record : records) {
            process(record);
        }
        consumer.commitSync();  // тільки після обробки всіх
    } catch (Exception e) {
        log.error("Processing failed, offsets not committed", e);
        // Не коммітимо → повідомлення будуть прочитані знову
    }
}

2. Async Commit with Fallback:

consumer.commitAsync((offsets, exception) -> {
    if (exception != null) {
        // Fallback to sync commit
        try {
            consumer.commitSync(offsets);
        } catch (Exception e) {
            log.error("Both async and sync commit failed", e);
        }
    }
});

3. Periodic Commit:

// Комміт кожні N секунд незалежно від батчів
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(() -> {
    consumer.commitAsync();
}, 0, 5, TimeUnit.SECONDS);

Performance Comparison

Latency overhead (per commit):
  Auto commit:     ~0ms (fire and forget)
  Async commit:    ~1ms (callback)
  Sync commit:     ~10-50ms (blocks)

Reliability:
  Auto commit:     Low (no error handling)
  Async commit:    Medium (callback, no retry)
  Sync commit:     High (retry, confirmation)

Monitoring

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

kafka.consumer:commit-latency-avg
kafka.consumer:commit-rate
kafka.consumer:failed-commit-rate
kafka.consumer:last-commit-latency

Best Practices

✅ Manual commit для production
✅ CommitSync для critical data
✅ CommitAsync для high-throughput
✅ Error handling для всіх коммітів
✅ Monitoring commit health

❌ Auto commit для production
❌ Auto commit для critical data
❌ Без обробки помилок комміту
❌ Mixed commit strategies
❌ Ігнорування commit latency

Архітектурні рішення

  1. Manual sync commit — стандарт для production
  2. Async commit з fallback — баланс performance/reliability
  3. Auto commit не рекомендується для production з критичними даними. Допустимий для: метрик, логів, real-time аналітики з acceptable loss.
  4. Error handling обов’язкова — retry або alert

Резюме для Senior

  • Auto commit коммітить отриманий, не оброблений offset
  • Manual commit забезпечує контроль над reliability
  • Sync commit для reliability, async для throughput
  • Error handling обов’язкова для production
  • Monitoring commit latency критичний для health checks

🎯 Шпаргалка для інтерв’ю

Обов’язково знати:

  • Auto commit: кожні auto.commit.interval.ms, коммітить отриманий (не оброблений!) offset
  • Manual commit: повний контроль, комміт ПІСЛЯ обробки — гарантія at-least-once
  • Sync commit: блокує до підтвердження (10-50ms), надійний; Async: не блокує, callback
  • Auto commit проблеми: offset lag (коммітить до обробки), interval mismatch
  • Async commit з fallback: при помилці → sync commit (єдина retry спроба)
  • Manual commit — стандарт для production; auto commit — тільки прототипи/тести
  • Mixed commit strategies = непередбачувана поведінка

Часті уточнюючі запитання:

  • Чому auto commit небезпечний? — Коммітить отриманий offset, не оброблений → при crash дані втрачені.
  • Що краще sync чи async? — Sync для reliability, async для throughput з fallback на error.
  • Як працює async commit fallback? — При помилці callback → sync commit → якщо і він впав → log error.
  • Auto commit — це broker-side? — Ні, це client-side logic в KafkaConsumer, не broker.

Червоні прапорці (НЕ говорити):

  • «Auto commit — хороший вибір для production» — коммітить до обробки
  • «Async commit без обробки помилок — норма» — втрата offsets
  • «Auto commit ініціюється брокером» — це client-side logic
  • «Можна змішувати auto і manual commit» — непередбачувана поведінка

Пов’язані теми:

  • [[13. Як працює commit offset]]
  • [[12. Що таке offset в Kafka]]
  • [[15. Що таке ребаланс і коли він відбувається]]
  • [[5. Що таке Consumer Group]]