Изучаем Apache Kafka с нуля. Урок 28. kafka-producer-perf-test.sh

Изучаем Apache Kafka с нуля. Урок 28. kafka-producer-perf-test.sh

 

В уроке 27 мы разбирали kafka-verifiable-producer.sh и kafka-verifiable-consumer.sh — утилиты, которые показывают каждое отправленное и полученное сообщение в виде JSON. Они хороши для отладки: видно, что именно ушло, какой офсет получили, есть ли потери. Но если нужно понять не «что» отправляется, а «как быстро» и «с какой задержкой» — там verifiable бессилен. Он не считает метрики.

Для нагрузочного тестирования продюсера в Kafka есть отдельная утилита — kafka-producer-perf-test.sh. Она гонит заданное количество сообщений с заданной скоростью и выдаёт точные цифры: пропускная способность в записях/секунду и мегабайтах/секунду, средняя и максимальная задержка, перцентили. Именно с неё начинается любой серьёзный разговор о производительности кластера.

Если вы занимаетесь администрированием кластера и вам нужно не просто запустить тест, но и правильно интерпретировать результаты, подобрать конфигурацию и сравнивать сценарии — эти темы детально разбираются в курсе «Администрирование кластера Kafka».

 

Чем kafka-producer-perf-test.sh отличается от verifiable-producer

Оба инструмента работают через продюсер Kafka, но задачи у них разные. kafka-verifiable-producer.sh создан для функциональной проверки: убедиться, что сообщения доходят, смотреть на офсеты, выявлять дубликаты или потери. kafka-producer-perf-test.sh создан для измерения производительности: он генерирует синтетическую нагрузку с контролируемым размером сообщений и скоростью, а потом отдаёт статистику.

Принципиальное отличие ещё и в том, что perf-test работает с фиксированным размером записи (—record-size в байтах), тогда как verifiable-producer шлёт структурированный JSON переменной длины. Это важно: при тестировании пропускной способности нужны однородные данные, чтобы цифры были воспроизводимыми.

 

Apache Kafka: администрирование кластера

Код курса
KAFKA
Ближайшая дата курса
13 июля, 2026
Продолжительность
24 ак.часов
Стоимость обучения
76 800

 

Параметры команды kafka-producer-perf-test.sh

Четыре параметра обязательны — без любого из них утилита завершится с ошибкой:

Флаг Значение Описание
—topic имя топика Куда отправляем сообщения
—num-records целое число Сколько записей отправить всего
—record-size байты Размер одной записи. Нельзя использовать вместе с —payload-file
—throughput записей/сек Лимит скорости. -1 означает без ограничений
—producer-props key=value Inline-параметры продюсера: bootstrap.servers и другие

Без —producer-props bootstrap.servers=… утилита не знает, куда подключаться. Это, считайте, пятый обязательный параметр на практике. Дополнительные параметры, которые часто используются:

Флаг Значение Описание
—producer.config путь к файлу Файл .properties с параметрами продюсера. Удобнее чем —producer-props при большом числе настроек
—payload-file путь к файлу Использовать строки из файла как тело сообщений. Нельзя вместе с —record-size
—print-metrics флаг Вывести расширенные JMX-метрики продюсера после теста
—transactional-id строка Включает транзакционный режим продюсера
—transaction-duration-ms мс Интервал коммита транзакции. Используется с —transactional-id

 

Как читать вывод

Утилита пишет два вида строк: промежуточные (каждые несколько секунд) и финальную итоговую строку в конце.

Промежуточные строки

Пока тест идёт, в консоль периодически выводится текущая статистика. Вот как это выглядит при отправке 1 миллиона записей по 1 КБ:

# Промежуточная строка - статистика за последний интервал
200000 records sent, 199800.0 records/sec (195.12 MB/sec), 3.8 ms avg latency, 87.0 ms max latency.
400000 records sent, 200400.2 records/sec (195.70 MB/sec), 3.5 ms avg latency, 61.0 ms max latency.
600000 records sent, 199600.1 records/sec (194.92 MB/sec), 3.7 ms avg latency, 54.0 ms max latency.

Первое число — сколько записей ушло на этот момент. Остальные метрики — за последний интервал, а не за весь тест. Поэтому промежуточные строки показывают текущий темп, но не итог.

 

Финальная строка

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

# Итоговая строка с перцентилями латентности
1000000 records sent, 198734.2 records/sec (194.08 MB/sec), 3.9 ms avg latency, 87.0 ms max latency, 3 ms 50th, 7 ms 95th, 19 ms 99th, 42 ms 99.9th.

Разберём каждую метрику по порядку:

  • records/sec — пропускная способность в записях в секунду за весь тест.
  • MB/sec — то же самое в мегабайтах. Считается как records/sec умноженное на record-size, делённое на 1 048 576.
  • avg latency — средняя задержка от момента вызова send() до получения подтверждения от брокера. Зависит от параметра acks.
  • max latency — максимальная задержка за весь тест. Часто сильно выше avg из-за GC-пауз или сетевых выбросов.
  • 50th / 95th / 99th / 99.9th — перцентили латентности. Цифра 50th означает, что половина запросов завершилась быстрее этого значения. 99.9th — самые медленные 0.1% запросов.

Для production-систем смотреть только на avg бессмысленно: если 99th percentile равен 500 мс, значит каждый сотый запрос ждёт полсекунды — и пользователь это почувствует.

Практическое использование утилиты kafka-producer-perf-test.sh

 Шаг 1. Базовый тест пропускной способности

Перед тестом создайте топик с нужным числом партиций. Для нагрузочного теста одной партиции обычно мало — продюсер упрётся в один брокер:

# Создаём топик для теста с 6 партициями и фактором репликации 3
kafka-topics.sh \
  --bootstrap-server localhost:9092 \
  --create \
  --topic perf-test \
  --partitions 6 \
  --replication-factor 3

Теперь базовый тест: 1 миллион записей по 1 КБ, без лимита скорости (throughput = -1), acks=1:

# Тест максимальной пропускной способности продюсера
# 1 000 000 записей по 1024 байта, без ограничения скорости
kafka-producer-perf-test.sh \
  --topic perf-test \
  --num-records 1000000 \
  --record-size 1024 \
  --throughput -1 \
  --producer-props bootstrap.servers=localhost:9092 acks=1

Параметр acks=1 означает, что брокер подтверждает запись только после того, как лидер-партиция сохранила её. Это стандартный режим: быстрее чем acks=all, но без гарантии на случай падения лидера сразу после подтверждения. Чтобы получить базовую цифру «сколько может кластер», начинают именно с acks=1.

 

Шаг 2. Тест с ограничением пропускной способности

Иногда важно не максимальная скорость, а поведение при фиксированной нагрузке: стабильна ли латентность, нет ли деградации при длительном тесте. Для этого устанавливают лимит через —throughput:

# Тест при фиксированной нагрузке 50 000 записей/сек, 5 минут (~15M записей)
# Запись 256 байт имитирует небольшие события (логи, события кликов)
kafka-producer-perf-test.sh \
  --topic perf-test \
  --num-records 15000000 \
  --record-size 256 \
  --throughput 50000 \
  --producer-props \
    bootstrap.servers=localhost:9092 \
    acks=all

При acks=all брокер ждёт подтверждения от всех реплик из ISR. Латентность вырастет, но зато данные не потеряются даже при отказе лидера. Сравнение результатов acks=1 против acks=all при одинаковой нагрузке — стандартный способ оценить «цену надёжности» в конкретном кластере.

 

Apache Kafka для инженеров данных

Код курса
DEVKI
Ближайшая дата курса
24 августа, 2026
Продолжительность
24 ак.часов
Стоимость обучения
76 800

 

Шаг 3. Тюнинг продюсера через —producer-props

Параметры продюсера напрямую влияют на результаты теста. Три ключевых:

  • batch.size — максимальный размер батча в байтах. По умолчанию 16 384 байта (16 КБ). Увеличение до 65 536 или 131 072 повышает пропускную способность при крупных сообщениях.
  • linger.ms — сколько миллисекунд продюсер ждёт перед отправкой батча, чтобы набрать побольше записей. По умолчанию 0 — отправляет сразу. Значение 5-20 мс может заметно поднять throughput при мелких сообщениях.
  • compression.type — сжатие: none, gzip, snappy, lz4, zstd. Снижает сетевую нагрузку и нагрузку на диск, но добавляет CPU на продюсере.

Вот пример теста с тюнингом под высокую пропускную способность:

# Тест с увеличенным батчом, linger.ms=5 и сжатием lz4
# Хорошо работает для потоков с мелкими и средними сообщениями
kafka-producer-perf-test.sh \
  --topic perf-test \
  --num-records 2000000 \
  --record-size 512 \
  --throughput -1 \
  --producer-props \
    bootstrap.servers=localhost:9092 \
    acks=1 \
    batch.size=65536 \
    linger.ms=5 \
    compression.type=lz4

Сравнивайте результаты по итоговой строке: смотрите не только на MB/sec, но и на перцентили. Иногда linger.ms повышает throughput, но поднимает avg latency — и это компромисс, который нужно осознанно принять для каждого конкретного случая.

 

Параметры через файл конфигурации

Когда параметров много, удобнее вынести их в файл и передать через —producer.config. Флаги —producer-props и —producer.config можно использовать вместе: props переопределяют значения из файла.

# producer-perf.properties
bootstrap.servers=broker1:9092,broker2:9092,broker3:9092
acks=all
batch.size=131072
linger.ms=10
compression.type=zstd
enable.idempotence=true
# Запуск теста с файлом конфигурации
kafka-producer-perf-test.sh \
  --topic perf-test \
  --num-records 1000000 \
  --record-size 1024 \
  --throughput -1 \
  --producer.config /etc/kafka/producer-perf.properties

Расширенные метрики через —print-metrics

Флаг —print-metrics добавляет к итоговому выводу подробные JMX-метрики самого продюсера: размер буфера, количество ретраев, время ожидания батча, record-queue-time и другие. Вывод длинный, но там есть полезные показатели для диагностики узких мест:

# Проверено: Apache Kafka 4.2.0, Ubuntu 22.04
# Запуск с выводом расширенных метрик продюсера
kafka-producer-perf-test.sh \
  --topic perf-test \
  --num-records 500000 \
  --record-size 1024 \
  --throughput -1 \
  --print-metrics \
  --producer-props bootstrap.servers=localhost:9092 acks=1

Обратите внимание на record-queue-time-avg — среднее время записи в очереди до отправки. Если оно растёт, значит продюсер не успевает отправлять и батчи копятся. Это сигнал либо на увеличение batch.size, либо на проблему на стороне брокера.

flowchart LR
    A["Параметры теста\n--num-records\n--record-size\n--throughput"] --> B["Генератор записей\nSyntheticPayload\nbytes x N"]
    B --> C["Продюсер Kafka\nbatch.size\nlinger.ms\ncompression"]
    C --> D["Брокер-лидер\nacks=1 или all"]
    D --> E["ISR реплики\n(при acks=all)"]
    D --> F["Подтверждение\nack"]
    F --> G["Сбор метрик\nlatency per record"]
    G --> H["Промежуточный вывод\nrecords/sec\nMB/sec\navg/max latency"]
    G --> I["Итоговая строка\n50th / 95th\n99th / 99.9th\npercentiles"]

 

Apache Kafka: администрирование кластера

Код курса
KAFKA
Ближайшая дата курса
13 июля, 2026
Продолжительность
24 ак.часов
Стоимость обучения
76 800

 

Что дальше

В уроке 29 разберём парную утилиту — kafka-consumer-perf-test.sh. Она тестирует уже не запись, а чтение: измеряет, с какой скоростью консьюмер вычитывает данные из топика, и помогает выявить узкие места на стороне консьюмера или сети.

Референсы

Все уроки курса

Тема Ссылка
1 Установка Kafka с Zookeeper https://bigdataschool.ru/blog/news/lesson1-kafka-zookeeper-install/
2 Установка Kafka в режиме KRaft https://bigdataschool.ru/blog/news/lesson2-kafka-kraft-install/
3 Docker KRaft: однонодовый кластер https://bigdataschool.ru/blog/news/lesson3-kafka-docker-single/
4 Docker KRaft: 3-нодовый кластер https://bigdataschool.ru/blog/news/lesson4-kafka-docker-cluster/
5 Утилиты bin/: переменные окружения и основы https://bigdataschool.ru/blog/news/lesson5-kafka-bin-intro/
6 kafka-topics.sh: управление топиками https://bigdataschool.ru/blog/news/lesson6-kafka-topics/
7 kafka-console-producer.sh https://bigdataschool.ru/blog/news/lesson7-kafka-console-producer/
8 kafka-console-consumer.sh https://bigdataschool.ru/blog/news/lesson8-kafka-console-consumer/
9 kafka-server-start.sh / kafka-server-stop.sh https://bigdataschool.ru/blog/news/lesson9-kafka-server-start-stop/
10 kafka-storage.sh https://bigdataschool.ru/blog/news/lesson10-kafka-storage/
11 kafka-cluster.sh https://bigdataschool.ru/blog/news/lesson11-kafka-cluster/
12 kafka-metadata-quorum.sh https://bigdataschool.ru/blog/news/lesson12-kafka-metadata-quorum/
13 kafka-metadata-shell.sh https://bigdataschool.ru/blog/news/lesson13-kafka-metadata-shell/
14 kafka-features.sh https://bigdataschool.ru/blog/news/lesson14-kafka-features/
15 kafka-configs.sh https://bigdataschool.ru/blog/news/lesson15-kafka-configs/
16 kafka-log-dirs.sh https://bigdataschool.ru/blog/news/lesson16-kafka-log-dirs/
17 kafka-dump-log.sh https://bigdataschool.ru/blog/news/lesson17-kafka-dump-log/
18 kafka-delete-records.sh https://bigdataschool.ru/blog/news/lesson18-kafka-delete-records/
19 kafka-consumer-groups.sh https://bigdataschool.ru/blog/news/lesson19-kafka-consumer-groups/
20 kafka-streams-application-reset.sh https://bigdataschool.ru/blog/news/lesson20-kafka-streams-reset/
21 kafka-leader-election.sh https://bigdataschool.ru/blog/news/lesson21-kafka-leader-election/
22 kafka-reassign-partitions.sh https://bigdataschool.ru/blog/news/lesson22-kafka-reassign-partitions/
23 kafka-replica-verification.sh https://bigdataschool.ru/blog/news/lesson23-kafka-replica-verification/
24 kafka-acls.sh https://bigdataschool.ru/blog/news/lesson24-kafka-acls/
25 kafka-broker-api-versions.sh https://bigdataschool.ru/blog/news/lesson25-kafka-broker-api-versions/
26 kafka-get-offsets.sh https://bigdataschool.ru/blog/news/lesson26-kafka-get-offsets/
27 kafka-verifiable-producer/consumer.sh https://bigdataschool.ru/blog/news/lesson27-kafka-verifiable/
28 kafka-producer-perf-test.sh https://bigdataschool.ru/blog/news/lesson28-kafka-producer-perf/
29 kafka-consumer-perf-test.sh https://bigdataschool.ru/blog/news/lesson29-kafka-consumer-perf/
30 kafka-mirror-maker.sh https://bigdataschool.ru/blog/news/lesson30-kafka-mirror-maker/
31 connect-standalone.sh https://bigdataschool.ru/blog/news/lesson31-kafka-connect-standalone/
32 connect-distributed.sh https://bigdataschool.ru/blog/news/lesson32-kafka-connect-distributed/
33 kcat. Альтернативный CLI https://bigdataschool.ru/blog/news/lesson33-kcat/