Що таке batch в Kafka producer
4. Buffer management — запобігання exhaustion
Рівень 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);
Типові помилки
- Маленький batch.size:
batch.size=1KB при throughput 10K msg/s → 10K запитів/сек замість ~100, навантаження на брокер x100. - linger.ms=0:
Відправляє одразу → батч не встигає заповнитися → Менше throughput - Маленький 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
Архітектурні рішення
- Batch size tuning — баланс між throughput і latency
- Linger.ms — час для заповнення батча
- Compression на батчі — кращий ratio
- 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-64KBlinger.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. Як дані розподіляються по партиціях]]