Что такое 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
Компрессия применяется к батчу целиком:
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
Если buffer заполнен:
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. Как данные распределяются по партициям]]