Перейти к содержанию

4. Производительность и тюнинг


Производительность Kafka упирается в детали producer/consumer и broker I/O. Здесь — production-практики по настройке:

  • producer: batch.size, linger.ms, acks
  • broker: num.network.threads, num.io.threads
  • consumer: max.poll.records
  • и как измерять trade-offs (latency vs throughput, durability vs speed) через нагрузочное тестирование.

Термины и сущности

Термин Определение
Batching Сбор нескольких сообщений в одну пачку для снижения overhead’а.
Linger Задержка перед отправкой партии сообщений, чтобы дождаться “достаточно много” данных.
acks Уровень подтверждения записи: насколько “надёжно” считаем запись успешной.
max.poll.records Максимум записей, которые consumer получит за один poll() (влияет на latency и обработку).
num.network.threads Кол-во сетевых обработчиков на broker (переработка запросов/сообщений).
num.io.threads Кол-во I/O обработчиков на broker (обслуживание чтения/записи).

Producer: batch.size, linger.ms, acks

batch.size: увеличиваем throughput, но следим за latency

Большие batch.size обычно:

  • увеличивают эффективность (меньше syscalls/overhead на сообщение),
  • улучшают throughput.

Риски:

  • рост linger/задержек,
  • более “толстые” пачки при burst’ах могут ухудшить tail latency.

Production подход:

  • подбирайте batch.size под размер сообщений и тип нагрузки,
  • измеряйте p95/p99 latency, а не только среднее.

linger.ms: даём “дозреть” батчу

linger.ms помогает, когда сообщения приходят неравномерно:

  • без linger мелкие сообщения отправляются чаще,
  • с linger есть шанс собрать их в одну партию.

Production best practice:

  • держите linger ограниченным (иначе latency может стать заметно выше),
  • начинайте с консервативных значений и двигайтесь итеративно через тесты.

acks: durability vs speed

Идея: насколько Kafka должна “успеть” сохранить данные, прежде чем producer считает запись успешной.

Таблица trade-offs:

acks Что означает Когда использовать
acks=1 достаточно лидера когда допустима потеря при отказе (или есть другой слой надёжности)
acks=all достаточно ISR и коммита production для надёжных потоков (финансовые/заказные события)
acks=-1 эквивалент all то же, что acks=all

Production recommendation:

  • если требуется “не потерять событие” — стартуйте с acks=all,
  • если нужно “максимально быстро” — тестируйте, но ожидайте более сложные failure/retry сценарии.

Broker threads: num.network.threads / num.io.threads

У broker’а есть два основных bottleneck’а:

  • сетевой обработчик (много запросов/подключений),
  • дисковый I/O обработчик (запись/чтение).

Производственная логика настройки

Best practice:

  • не меняйте threads “на глаз”,
  • сначала наблюдайте: где очередь и где растёт задержка,
  • делайте изменения после того, как вы поняли профиль bottleneck’а.

Пример фрагмента server.properties (как ориентир, а не “универсальные значения”):

# broker config (пример)
num.network.threads=6
num.io.threads=8

Комментарий:

  • конкретные значения зависят от CPU/кол-ва коннектов/типа диска и профиля IO,
  • корректнее подбирать на performance стенде, максимально близком к production.

Consumer: max.poll.records и обработка

max.poll.records напрямую влияет на:

  • время обработки batch’а,
  • вероятность “увидеть ребаланс/rebalance timeout”, если обработка пачки занимает слишком много времени.

Production best practice:

  • выбирайте max.poll.records так, чтобы обработчик укладывался в SLA по времени на одну итерацию,
  • при долгой обработке сообщений — увеличивайте параллелизм внутри consumer’а/worker’ов, но не “раздувайте” max.poll.records бесконтрольно.

Мини-идея для практики:

  • если вы обрабатываете сообщения “тяжело” (DB/HTTP) — держите batch меньше и ускоряйте обработку worker’ами.

Нагрузочное тестирование: kafka-producer-perf-test

Цель теста:

  • проверить, как изменения batch.size/linger/acks меняют throughput и latency,
  • сравнить режимы “быстро” vs “надёжно”.

Пример команды (использую короткий флаг -t, имя раздела задаётся без длинного флага):

bin/kafka-producer-perf-test.sh \
  -t benchmark-orders \
  --num-records 5000000 \
  --record-size 800 \
  --throughput 100000 \
  --producer-props \
acks=all,batch.size=32768,linger.ms=20,compression.type=snappy \
  --bootstrap-server kafka-0.kafka:9092

Комментарии:

  • compression.type часто даёт прирост throughput при CPU-индуцированной стоимости,
  • throughput в тесте задаёт целевую скорость (важно фиксировать, иначе сравнение режимов будет некорректным).

Анализ latency/throughput:

  • смотрите не только average throughput, но и latency percentiles,
  • сравнивайте p95/p99 между конфигами.

Мини-код: проверка producer batch поведения (kcat)

Хотя kcat не настраивает producer так же детально, это удобный инструмент для быстрой проверки “что именно уходит”:

Producer (быстрый push)

kcat -b kafka-0:9092 -t benchmark-orders -P -K:

Комментарий:

  • -K: задаёт разделитель ключ/значение при вводе,
  • для реального тюнинга всё равно используйте perf-test + реальный producer клиент.

Production checklist

Настройка Делайте так Избегайте
batch.size подбирайте под размер сообщений и throughput “огромный batch без замеров p99”
linger.ms ограниченный linger + тесты linger, который раздувает tail latency
acks для надёжности используйте acks=all и тестируйте retry acks=1 без понимания failure/dup сценариев
broker threads сначала наблюдайте bottleneck, потом меняйте “перенастройку ради перенастройки”
max.poll.records под SLA обработки (и чтобы не рушить polling) слишком большой poll batch при долгой обработке