Вопрос 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

Компрессия применяется к батчу целиком:
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

Архитектурные решения

  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. Как данные распределяются по партициям]]