Вопрос 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. Что такое rebalancing и когда он происходит]]
  • [[5. Что такое Consumer Group]]