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

Що таке batch в Kafka producer

4. Buffer management — запобігання exhaustion

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

Рівень Junior

Визначення

Batch — це механізм, при якому продюсер накопичує повідомлення і відправляє їх пакетом замість одного за раз.

Без batch:
  msg1 → запит
  msg2 → запит
  msg3 → запит
  3 запити до брокера

З batch:
  [msg1, msg2, msg3] → 1 запит
  1 запит до брокера

Навіщо потрібен batch?

✅ Більше throughput (менше запитів)
✅ Менша latency на повідомлення
✅ Краще використання network

Основні налаштування

props.put("batch.size", 16384);       // 16KB — розмір батча
props.put("linger.ms", 5);            // чекати 5ms для заповнення
props.put("buffer.memory", 33554432); // 32MB — буфер в пам'яті

Рівень Middle

Як працює batching

1. Продюсер викликає send(record)
2. Повідомлення додається в батч для партиції
3. Батч відправляється коли:
   - Досягнуто batch.size
   - Минув linger.ms
   - Producer викликав flush()

Batch Size

// Маленький batch.size
props.put("batch.size", 1024);  // 1KB
// → Часті відправки, менше throughput

// Великий batch.size
props.put("batch.size", 65536);  // 64KB
// → Рідкі відправки, більше throughput, більше memory

Linger.ms

// linger.ms=0 — відправляти одразу
props.put("linger.ms", "0");
// → Мінімальна latency, менше throughput

// linger.ms=5 — чекати 5ms
props.put("linger.ms", "5");
// → Більше throughput, трохи більше latency

Buffer Memory

// Буфер для зберігання батчів, що очікують відправки
props.put("buffer.memory", 33554432);  // 32MB

// Якщо буфер заповнений:
// max.block.ms — скільки чекати перед помилкою
props.put("max.block.ms", 60000);

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

  1. Маленький batch.size:
    batch.size=1KB при throughput 10K msg/s → 10K запитів/сек замість ~100,
    навантаження на брокер x100.
    
  2. linger.ms=0:
    Відправляє одразу → батч не встигає заповнитися
    → Менше throughput
    
  3. Маленький buffer.memory:
    buffer.memory=1MB → швидко заповнюється
    → Producer блокується або викидає помилку
    

Рівень Senior

Internal Implementation

RecordAccumulator:

Продюсер використовує RecordAccumulator для batching:
- Один батч на партицію
- Батчі відправляються коли заповняться або по linger.ms
- Compression застосовується до батча цілком

Batch Completion:

Батч вважається повним коли:
1. Досягнуто batch.size (bytes)
2. Минув linger.ms (time)
3. Викликано flush()
4. Producer closed

Compression і Batching

Compression застосовується до батча цілком:
props.put("compression.type", "lz4");

Переваги:
- Більший батч → кращий compression ratio
- Менше network I/O
- Менше CPU на брокері

Performance Tuning

# High throughput configuration
batch.size: 65536          # 64KB
linger.ms: 10              # чекати 10ms
buffer.memory: 67108864    # 64MB
compression.type: lz4
max.in.flight.requests.per.connection: 5

# Low latency configuration
batch.size: 16384          # 16KB
linger.ms: 0               # не чекати
buffer.memory: 33554432    # 32MB
compression.type: none (в сучасних версіях lz4 має мінімальний overhead ~1-2% CPU,
тому часто рекомендується навіть для low-latency).
max.in.flight.requests.per.connection: 1

Memory Management

Total memory usage:
  buffer.memory + (batch.size * num_partitions * in_flight)

Приклад:
  32MB buffer + (64KB * 100 partitions * 5 in-flight)
  = 32MB + 32MB = 64MB

Якщо буфер заповнений:
  Producer блокується на max.block.ms
  → Потім викидає BufferExhaustedException

Monitoring

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

kafka.producer:batch-size-avg
kafka.producer:batch-size-max
kafka.producer:compression-rate-avg
kafka.producer:buffer-available-bytes
kafka.producer:buffer-exhausted-rate
kafka.producer:record-send-rate

Alerts:

- Buffer exhausted rate > 0 → critical
- Average batch size < 1KB → investigate
- Compression rate < 1.5 → check compression config

Best Practices

✅ batch.size=32KB-64KB для throughput
✅ linger.ms=5-10ms для batching
✅ compression=lz4 для network savings
✅ monitor batch size і buffer usage
✅ buffer.memory достатньо для workload

❌ batch.size=0 або занадто маленький
❌ linger.ms=0 коли потрібен throughput
❌ buffer.memory занадто маленький
❌ Без моніторингу batch metrics
❌ Compression без batching

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

  1. Batch size tuning — баланс між throughput і latency
  2. Linger.ms — час для заповнення батча
  3. Compression на батчі — кращий ratio
  4. Buffer management — запобігання exhaustion

Резюме для Senior

  • Batching — ключовий механізм для throughput
  • batch.size і linger.ms — основні tuning параметри
  • Compression застосовується до батча цілком
  • Buffer memory management критичний для stability
  • Monitoring batch metrics обов’язковий для production

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

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

  • Batch — накопичення повідомлень і відправка пакетом замість одного за раз
  • Батч відправляється коли: досягнуто batch.size, минув linger.ms, або викликано flush()
  • batch.size=16KB за замовчуванням; для throughput: 32KB-64KB
  • linger.ms=0 за замовчуванням (відправляти одразу); для batching: 5-10ms
  • Compression застосовується до батча цілком — більший батч = кращий compression ratio
  • Buffer memory (32MB за замовчуванням) — при заповненні producer блокується
  • RecordAccumulator — внутрішній механізм batching, один батч на партицію

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

  • Що буде при batch.size=0? — Відправка по одному повідомленню, x100 навантаження на брокер.
  • Навіщо linger.ms якщо batch.size заповнюється? — Для low-throughput батч не заповнюється, linger.ms дає час накопичити.
  • Що при buffer exhaustion? — Producer блокується на max.block.ms → BufferExhaustedException.
  • Як compression впливає на batching? — Застосовується до батча цілком, більший батч = кращий ratio.

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

  • «linger.ms=0 — оптимальний вибір для throughput» — батч не встигає заповнитися
  • «batch.size не важливий» — визначає кількість запитів до брокера
  • «Compression на кожному повідомленні» — на батчі цілком
  • «Buffer memory можна не налаштовувати» — при high-throughput швидко заповнюється

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

  • [[22. Як працює компресія повідомлень]]
  • [[4. Що таке ключ повідомлення і як він впливає на партиціонування]]
  • [[23. Що таке idempotent producer]]
  • [[3. Як дані розподіляються по партиціях]]