Как выбрать инструмент для нагрузочного тестирования серверов и сервисов
Для нагрузочного тестирования серверов и инфраструктуры нет универсального инструмента. Выбор зависит от объекта проверки: процессор и память тестируют sysbench и stress-ng, дисковую подсистему и хранилища - fio, сетевой канал - iperf3, HTTP/API-сервисы - k6, базы данных - pgbench и sysbench OLTP. Генератор HTTP-запросов не измерит IOPS диска, а fio не покажет предел производительности API. Сначала определите, какой компонент проверяете, затем подбирайте профиль нагрузки и метрики.
Быстро сузить выбор помогает таблица соответствия задачи и инструмента:
| Компонент | Инструмент | Ключевые метрики | Типичное ограничение |
|---|---|---|---|
| CPU, память | sysbench, stress-ng | Время выполнения, throughput, нагрузка на ядра | Частота, число ядер, NUMA, лимиты cgroup |
| Блочные устройства, файловые системы, RAID, ZFS | fio | IOPS, пропускная способность, latency (p50, p95, p99) | Тип диска, размер блока, глубина очереди, кеш |
| Сеть между узлами | iperf3 | Пропускная способность, jitter, packet loss | RTT, TCP window, CPU на sender/receiver |
| HTTP/API | k6, wrk, wrk2 | RPS, latency percentiles, error rate | Мощность генератора, реалистичность сценария |
| PostgreSQL | pgbench | TPS, latency, число транзакций | Кеш, блокировки, диск |
| MySQL/MariaDB | sysbench OLTP | TPS, latency, число транзакций | Кеш, блокировки, диск |
| Kubernetes | k6 + метрики узлов и pod | Latency, error rate, CPU throttling | Лимиты pod, сетевой overlay, ingress |
Таблица задаёт стартовую точку. Далее разберём, чем отличаются типы тестов и как не ошибиться с интерпретацией.
Бенчмарк, стресс-тест и нагрузочный тест: какую задачу решает каждый подход
Путаница между бенчмарком, стресс-тестом и нагрузочным тестированием приводит к выбору неподходящего инструмента и неверным выводам. Различия простые:
- Бенчмарк измеряет производительность изолированного компонента в контролируемых условиях. Пример: sysbench CPU считает простые числа, fio выполняет последовательное чтение с заданным размером блока. Цель - сравнить железо или конфигурации между собой.
- Стресс-тест проверяет поведение системы на предельной или аварийной нагрузке. Пример: stress-ng нагружает все ядра и память до 100%, чтобы увидеть throttling, перегрев или OOM. Цель - найти границу стабильности и проверить реакцию мониторинга.
- Нагрузочное тестирование воспроизводит ожидаемый рабочий профиль. Пример: k6 имитирует 500 пользователей, которые логинятся, просматривают товары и оформляют заказы в пропорциях из production-наблюдений. Цель - проверить выполнение SLO сервиса.
Выбор подхода зависит от вопроса: сравнить железо, найти предел системы или проверить выполнение требований сервиса. Не используйте бенчмарк для доказательства готовности к пиковой нагрузке, а стресс-тест - для сравнения двух серверов по производительности.
Матрица выбора: CPU, диск, сеть, веб-приложение, база данных и Kubernetes
Матрица из первого раздела покрывает основные сценарии. Для каждого компонента важно понимать, что именно измеряется:
- CPU/RAM: sysbench CPU выполняет вычисления с фиксированным числом потоков и количеством запросов. Результат - время выполнения и events per second. stress-ng создаёт нагрузку на ядра, память, VM и I/O. Метрики: load average, CPU utilization, температура, throttling, OOM events.
- Блочные устройства и файловые системы: fio генерирует I/O-операции с заданными параметрами: последовательные или случайные, размер блока, глубина очереди, число потоков, buffered или direct I/O. Метрики: IOPS, пропускная способность, latency percentiles.
- Сеть между узлами: iperf3 измеряет пропускную способность TCP/UDP, потери пакетов и jitter. Метрики: bandwidth, retransmits, packet loss.
- HTTP/API: k6, wrk или wrk2 отправляют HTTP-запросы по сценарию. Метрики: RPS, latency (p50, p95, p99), error rate, timeouts.
- PostgreSQL: pgbench выполняет стандартные транзакции TPC-B. Метрики: TPS, latency, число транзакций.
- MySQL/MariaDB: sysbench OLTP выполняет операции чтения/записи в таблицах. Метрики: TPS, latency, число транзакций.
- Kubernetes: k6 с внешним генератором плюс метрики узлов и pod. Метрики: latency, error rate, CPU throttling, memory working set, restarts.
Для каждого пункта указаны типичные ограничения, которые мешают получить ожидаемый результат. Например, один TCP-поток iperf3 может не заполнить высокоскоростной канал из-за RTT или TCP window. fio с buffered I/O покажет производительность page cache, а не диска. k6 из перегруженного генератора даст заниженные цифры.
Что зафиксировать до тестирования производительности инфраструктуры
Результат теста имеет ценность только при возможности сравнения. До запуска зафиксируйте конфигурацию стенда и проверяемую гипотезу. Иначе получите набор цифр, который не объясняет причину изменения производительности.
Сформулируйте проверяемую гипотезу и критерий результата
Тестирование начинается с инженерного предположения, а не с запуска команды. Примеры гипотез:
- Новый SSD уменьшит p99 latency записи с 5 мс до 2 мс при случайной нагрузке 4K block size и queue depth 32.
- Настройка Nginx (увеличение worker_processes, включение keepalive) повысит RPS на 20% без роста доли 5xx ошибок.
- Изменение recordsize в ZFS с 128K на 1M улучшит профиль последовательного чтения для медиафайлов на 30%.
- Новый лимит CPU для контейнера (с 0.5 до 1.0) исключит CPU throttling и снизит p99 latency API на 15%.
Для каждой гипотезы определите метрику, допустимый уровень ошибок и условия, при которых изменение считается успешным. Например: «p99 latency записи не превышает 2 мс, потерь данных нет, iostat не показывает очереди более 10». Без критерия результата невозможно принять решение о внедрении изменения.
Уберите факторы, которые искажают результаты
Кеширование, фоновая активность и различия среды делают сравнение недостоверным. Основные факторы:
- Page cache и ARC ZFS: повторное чтение данных может идти из памяти, а не с диска. Используйте direct I/O (fio с
--direct=1) или очищайте кеш перед прогоном, если нужно измерить физический диск. - Прогрев приложения: JIT-компиляция, кеши в приложении и базе данных искажают первые минуты теста. Выполняйте прогрев перед основным прогоном.
- Фоновые задачи: backup, репликация, antivirus/EDR, соседние виртуальные машины, CPU steal time, сетевой шейпинг и autoscaling изменяют доступные ресурсы. Проводите тест на отдельном стенде или в согласованное окно.
- Различия среды: версии ядра и ПО, настройки виртуальной машины или контейнера, лимиты cgroup, конфигурация приложения, объем и профиль тестовых данных должны быть одинаковыми для сравниваемых состояний.
Рекомендуем отдельный стенд или согласованное окно, одинаковые входные данные, несколько прогонов и фиксацию медианы и разброса. Минимальный паспорт прогона: модель CPU, объем RAM, тип и число дисков, RAID/ZFS-пул, сетевые интерфейсы, версии ядра и ПО, настройки виртуальной машины или контейнера, лимиты cgroup, конфигурация приложения, объем и профиль тестовых данных. Тест сравнивает не абстрактные цифры, а конкретные состояния системы до и после изменения.
Чем тестировать производительность CPU и памяти сервера
CPU-тесты оценивают не только количество ядер: важны частота, NUMA, CPU governor, виртуализация, лимиты cgroup и steal time. Разделяйте короткий сравнительный бенчмарк и длительную проверку стабильности под нагрузкой.
sysbench: быстрое сравнение вычислительной производительности
sysbench CPU - удобный способ сравнить время выполнения одинакового набора вычислений при фиксированных threads и max-requests. Пример команды:
sysbench cpu --cpu-max-prime=20000 --threads=4 --time=60 runРезультат показывает общее время, events per second и latency. Используйте его для сравнения серверов, VM или последствий изменения лимитов контейнера. Результат нельзя переносить напрямую на производительность конкретного backend-приложения, Python-задачи или базы данных без профильного теста. sysbench CPU нагружает только арифметические операции, не затрагивая память, диск или сеть.
stress-ng: проверка поведения сервера при предельной нагрузке
stress-ng нужен, когда проверяете стабильность, throttling, перегрев или реакцию мониторинга, а не получаете маркетинговую цифру производительности. Он умеет нагружать CPU, память, VM и I/O. Примеры:
# Нагрузить все ядра CPU на 10 минут
stress-ng --cpu 0 --timeout 10m
# Нагрузить память (выделить 80% RAM)
stress-ng --vm 2 --vm-bytes 80% --timeout 10m
# Комбинированная нагрузка
stress-ng --cpu 4 --io 2 --vm 2 --vm-bytes 1G --timeout 10mПредупреждаем: stress-ng может вызвать перегрев, OOM, деградацию соседних сервисов. Запускайте такие проверки на стенде либо в согласованное окно. Во время прогона фиксируйте load average, CPU utilization, температуру, throttling, OOM events и latency зависимых сервисов.
Инструменты для тестирования дисков, RAID и ZFS-хранилищ
Измерение производительности дисковой подсистемы - самый рискованный сценарий: можно повредить данные или получить неверные ожидания от IOPS. Основной инструмент - fio. Он генерирует I/O-операции с заданными параметрами и выдаёт подробную статистику.
fio: как подобрать профиль под реальную дисковую нагрузку
Не запускайте случайный fio-профиль, который измеряет сценарий, отсутствующий в рабочей системе. Определите, какие операции преобладают: последовательные или случайные, размер блока, глубина очереди, параллелизм, buffered или direct I/O, fsync и latency percentiles. Примеры выбора профиля:
- Большие последовательные блоки для backup и media:
--rw=read --bs=1M --iodepth=16 --numjobs=1. - 4K/8K random read-write для СУБД:
--rw=randrw --bs=4k --iodepth=32 --numjobs=4. - Смешанный профиль для виртуальных машин:
--rw=randrw --bs=64k --iodepth=16 --numjobs=2.
Используйте тестовые файлы на отдельном dataset или томе. Никогда не указывайте в качестве target само блочное устройство с данными: fio с параметром --filename=/dev/sda и записью уничтожит содержимое. Безопасно создавать файл внутри файловой системы: --filename=/mnt/testfile --size=10G. Для тестирования сырого устройства используйте отдельный диск без данных.
Пример команды fio для случайного чтения с direct I/O:
fio --name=randread --ioengine=libaio --rw=randread --bs=4k --numjobs=4 --iodepth=32 --size=10G --runtime=60 --time_based --direct=1 --filename=/mnt/testfileРезультат покажет IOPS, пропускную способность и latency percentiles. Сравнивайте p99 latency, а не только среднее значение.
Особенности тестирования ZFS, NAS и сетевых хранилищ
В системах ZFS производительность зависит от кеша, layout пула и синхронных записей. Учитывайте:
- ARC: повторное чтение может идти из кеша. Для теста физического диска используйте
--direct=1или очищайте ARC. - recordsize: влияет на производительность последовательных и случайных операций. Тестируйте с разными значениями, если планируете менять.
- compression: сжатие ускоряет чтение и запись сжимаемых данных, но добавляет CPU. Отключайте для чистого теста диска.
- sync: синхронные записи (например, для NFS) требуют ZIL/SLOG. Отключение sync ради бенчмарка не отражает безопасную production-конфигурацию.
- Состояние resilver/scrub: фоновые операции снижают производительность. Проверяйте
zpool status. - Заполненность пула: при заполнении выше 80-90% производительность падает. Тестируйте на пуле с реалистичным заполнением.
- RAIDZ и mirrors: разная производительность и отказоустойчивость. Тестируйте конкретную конфигурацию.
Разграничивайте локальный тест пула и клиентский тест по NFS/SMB/iSCSI. Во втором случае итог ограничивают также сеть, протокол и клиентский кеш. Для клиентского теста используйте fio на клиенте с файлом на смонтированном ресурсе.
Чем тестировать сеть между серверами и узлами кластера
Сетевой канал проверяют iperf3. Он измеряет пропускную способность TCP/UDP, потери пакетов и jitter. Это помогает отделить проблему сети от проблем приложения, диска или шифрования трафика.
iperf3: пропускная способность, параллельные потоки и UDP-потери
iperf3 работает в модели server/client. На одном узле запускается сервер: iperf3 -s. На другом - клиент: iperf3 -c . Базовый тест TCP показывает пропускную способность одного потока. Для заполнения высокоскоростного канала используйте несколько потоков: iperf3 -c . Длительность задаётся флагом -t 30. Для reverse-направления: iperf3 -c .
UDP-тест измеряет jitter и packet loss: iperf3 -c . Один TCP-поток может не заполнить канал из-за RTT, TCP window или ограничений CPU. Запускайте тест в обоих направлениях, проверяйте MTU, скорость линка, ошибки интерфейса, CPU на sender/receiver и маршрут между узлами.
Почему результат iperf3 не равен производительности веб-сервиса
Хороший bandwidth не гарантирует высокую производительность API или хранилища. iperf3 передаёт поток данных без TLS, HTTP, DNS, балансировщика, Nginx, сериализации, backend, БД и дисковой подсистемы. Каждый слой добавляет задержки. Используйте iperf3 для проверки транспортного уровня, а k6 или другой генератор протокольной нагрузки - для пользовательского сценария.
Инструменты для нагрузочного тестирования веб-приложений и API
Для проверки сервисов через реальный HTTP/API-путь используйте k6. Он позволяет писать сценарии на JavaScript, задавать пороги и анализировать процентили задержек.
k6: сценарии пользователей, пороги и percentiles
k6 моделирует виртуальных пользователей, выполняющих HTTP-запросы по сценарию. Пример простого сценария:
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '30s', target: 50 },
{ duration: '1m', target: 50 },
{ duration: '30s', target: 0 },
],
thresholds: {
http_req_duration: ['p(95)<500'],
http_req_failed: ['rate<0.01'],
},
};
export default function () {
const res = http.get('https://example.com/api/products');
check(res, { 'status is 200': (r) => r.status === 200 });
sleep(1);
}Ключевые метрики: p50, p95, p99 latency, RPS, error rate, timeouts и доля успешных ответов. Моделируйте аутентификацию, чтение, запись, паузы и соотношение операций по данным production-наблюдений. Генератор нагрузки должен иметь запас ресурсов и обычно размещается вне тестируемого узла.
wrk, wrk2 и JMeter: когда нужны более узкие инструменты
wrk подходит для быстрой HTTP-проверки и поиска ориентировочного предела простого endpoint. wrk2 нужен, когда важна постоянная интенсивность запросов и анализ latency под фиксированной нагрузкой. JMeter используйте для сложных протоколов, цепочек запросов и команд, уже использующих его экосистему. Ограничения: результаты зависят от мощности load generator, реалистичности сценария и распределения тестовых данных.
Как тестировать базы данных и сервисы хранения данных
Для СУБД нужен профильный генератор нагрузки и реалистичный объем данных, превышающий кеш там, где это важно. Результаты связывайте с блокировками, планами запросов, replication lag, checkpoint, WAL/binlog, cache hit ratio и latency диска.
pgbench и sysbench OLTP: профильная нагрузка для PostgreSQL и MySQL
pgbench применяется для PostgreSQL. Инициализируйте тестовую базу: pgbench -i -s 100 mydb. Запустите тест: pgbench -c 10 -j 2 -T 60 mydb. Настройте масштаб данных, число соединений, read-only/read-write профиль и длительность прогона. Стандартная схема бенчмарка не заменяет тест с реальными таблицами, индексами и SQL-запросами приложения.
sysbench OLTP используется для MySQL/MariaDB. Подготовьте таблицы: sysbench oltp_read_write --mysql-host=localhost --mysql-user=root --mysql-password=pass --mysql-db=test --tables=10 --table-size=100000 prepare. Запустите тест: sysbench oltp_read_write --mysql-host=localhost --mysql-user=root --mysql-password=pass --mysql-db=test --tables=10 --table-size=100000 --threads=16 --time=60 run.
Почему тест СУБД нужно сопровождать метриками и логами
Во время прогона собирайте latency запросов, active connections, locks, cache hit ratio, WAL/binlog activity, checkpoint, IOPS, disk latency, CPU и память. Логи и трейсы используйте для выявления медленных запросов и ошибок зависимостей. Не делайте вывод по одной метрике transactions per second. Например, рост TPS при увеличении числа соединений может сопровождаться ростом latency и блокировок.
Нагрузочное тестирование контейнеров, Kubernetes и микросервисов
В Kubernetes проблема может возникать на уровне pod, node, ingress или межсервисного взаимодействия. Определите три уровня проверки: компонент внутри контейнера, сервис через ClusterIP/Ingress и весь пользовательский путь через внешний endpoint. Тест только из pod может скрыть проблемы DNS, ingress, TLS, сетевых политик и балансировки, а внешний тест не всегда локализует узкое место.
Где размещать генератор нагрузки в Kubernetes
Сопоставьте внешний load generator, отдельный pod и выделенный node. Риски: shared CPU, лимиты cgroup, network overlay, NAT, недостаток ephemeral storage и конкуренция с тестируемыми workload. Для масштабных прогонов отделяйте генератор от целевого кластера.
Какие метрики смотреть на уровне pod, node и ingress
Проверяйте CPU throttling, memory working set, OOMKilled, restarts, request/limit utilization, node pressure, disk latency, network drops, ошибки ingress и latency upstream. Для микросервисов сопоставляйте метрики с логами и трассировками, чтобы отличить медленный backend от перегруженного входного сервиса.
Как построить воспроизводимый сценарий и интерпретировать результаты
Соберите отдельные инструменты в повторяемый рабочий процесс: от baseline до решения о внедрении изменения. Пошаговый алгоритм:
- Сформулируйте гипотезу и критерий результата.
- Подготовьте стенд и данные.
- Включите мониторинг.
- Выполните прогрев.
- Проведите несколько одинаковых прогонов.
- Сравните медиану и хвостовые задержки.
- Сохраните конфигурацию и исходные результаты.
Собирайте системные метрики параллельно с тестом
Для доказуемого вывода о причине изменения производительности собирайте CPU utilization и load, memory pressure, swap, iowait, IOPS, disk latency, network throughput, retransmits, ошибки приложения и saturation пулов. Для инфраструктуры используйте доступные источники: SNMP для сетевого оборудования, IPMI для аппаратного состояния серверов, метрики временных рядов в VictoriaMetrics, логи в ClickHouse и данные приложения в PostgreSQL или иной используемой системе.
Сравнивайте не только среднее значение, но и задержки, ошибки и стабильность
Сравнивайте median, p95, p99, max latency, throughput, error rate, timeout rate и разброс между прогонами. Рост throughput при ухудшении p99 или увеличении 5xx не всегда означает улучшение. Зафиксируйте критерии отката или доработки изменения.
Типичные ошибки при стресс-тестировании серверов и инфраструктуры
Чек-лист ошибок: запуск fio с записью по production-device, тест одного прогрева, сравнение разных версий ПО, тест из перегруженного генератора, игнорирование кешей, измерение только RPS, отсутствие мониторинга, выводы по одному запуску и нагрузка на production без ограничений.
Когда тест нельзя запускать в production
Не проводите деструктивные I/O-тесты, стресс-тесты памяти и CPU или неконтролируемый высокий HTTP-трафик на production без изоляции, лимитов, окна работ и плана остановки. Для критичных систем используйте production-подобный стенд, read-only сценарии либо строго ограниченный canary-тест.
Что сохранить вместе с результатом теста
Сохраняйте команды и версии инструментов, конфигурацию сервера и приложения, параметры виртуализации или Kubernetes, профиль тестовых данных, сырые результаты, графики метрик, логи ошибок и дату прогона. Это превращает разовую проверку в основу для дальнейших технических решений.
Завершающее дерево выбора: компонент -> профиль нагрузки -> метрики -> инструмент -> повторные прогоны.