SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Как правильно протестировать производительность VPS

Узнайте, как объективно оценить мощность VPS с помощью yabs.sh, fio, sysbench и iperf3. Мы объясняем, почему разовый тест неинформативен и как учитывать влияние соседей по серверу.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Что означает бенчмаркинг VPS

Бенчмаркинг VPS подразумевает измерение четырех показателей: скорость работы одного ядра CPU, пропускная способность оперативной памяти, количество мелких операций ввода-вывода (IOPS) дисковой подсистемы в секунду и пропускная способность сетевого канала. Один запуск yabs.sh позволяет получить результаты по CPU, диску и сети примерно за 10 минут; для измерения пропускной способности памяти используйте отдельный тест, приведенный ниже. Интерпретация результатов — более сложная задача, так как VPS (виртуальный выделенный сервер) использует общее физическое оборудование с другими арендаторами. В результате на одной и той же машине показатели в 03:00 и в 20:00 могут существенно различаться.

План действий заключается в запуске yabs.sh для получения общей картины, а затем в ручном запуске инструментов, описанных ниже. Самостоятельный запуск позволяет изменять флаги, наблюдать за изменением показателей и понимать, что именно измеряет конкретный параметр. Выполняйте тестирование после настройки машины, а не до нее. Сначала необходимо выполнить шаги из первые десять минут на новом VPS, так как сервер, на котором еще идет процесс первичного обновления, покажет низкие результаты по причинам, не связанным с аппаратным обеспечением.

Изучите машину перед проведением замеров

Половина всех некорректных бенчмарков связана с тем, что автор не понимал устройство машины.

nproc
lscpu | grep -E 'Model name|Hypervisor|Thread'
free -h
df -hT /
uname -r
systemd-detect-virt

Hypervisor vendor: KVM означает полную виртуализацию, при которой вы используете собственное ядро. Вывод systemd-detect-virt в виде lxc или openvz указывает на контейнерную виртуализацию: вы используете общее ядро хоста, а лимиты CPU и памяти задаются через cgroup (control group), а не через виртуальное оборудование. В системе с cgroup v2 вы можете прочитать лимит CPU из cgroup вашего контейнера; указанный ниже путь актуален, если эта cgroup смонтирована в /sys/fs/cgroup.

cat /sys/fs/cgroup/cpu.max

max 100000 означает, что у данной cgroup нет собственной квоты; однако её могут ограничивать родительские cgroup. 200000 100000 означает, что вы можете использовать 200000 микросекунд процессорного времени в каждом периоде длительностью 100000 микросекунд, что эквивалентно квоте в два ядра. Тариф, заявленный как 4 vCPU с квотой в два ядра, никогда не покажет производительность четырех ядер. Инструменты для бенчмаркинга могут выявить это ограничение: VoxelBench сообщает о квотах CPU и помечает процессор как разделяемый или ограниченный (throttled), если хост предоставляет гораздо больше ядер, чем может использовать сервер.

df -hT / важен по другой причине: из-за столбца Type. Если там указано overlay, значит, вы находитесь внутри контейнера, и результаты тестирования диска будут описывать ту систему хранения, которая находится под этим оверлеем. Зафиксируйте это сейчас.

Мониторинг steal time в реальном времени

Steal time — это доля времени, в течение которого ваш виртуальный процессор вынужденно простаивал, так как гипервизор не предоставил ему вычислительные ресурсы. Это полезный индикатор нехватки процессорного времени, однако он не позволяет различить нагрузку от соседних виртуальных машин и принудительное ограничение CPU со стороны провайдера.

vmstat 1 10

Следите за столбцом st в правой части экрана. Постоянно высокий показатель steal time означает, что гостевой системе не хватает процессорных ресурсов, но значение выше 5% не всегда доказывает переподписку (oversubscription) ресурсов хоста. Провайдеры могут намеренно отображать принудительное ограничение квот CPU как steal time. В top отображается то же значение, что и в %st в строке CPU. Запустите vmstat 1 во втором SSH-сеансе во время проведения тестов производительности и записывайте значение steal time рядом с каждым результатом.

Начните с yabs.sh

yabs.sh (Yet Another Bench Script) — это shell-скрипт, который запускает fio, iperf3 и Geekbench, выводя итоговый отчет. Он использует уже установленные fio и iperf3, а при их отсутствии загружает статические бинарные файлы. Это стандартный инструмент для обсуждения производительности VPS, поэтому вывод yabs — самый быстрый способ сравнить показатели с другими пользователями.

Официальная команда для запуска в одну строку выглядит так.

curl -sL yabs.sh | bash

Она передает содержимое, полученное по URL, напрямую в интерпретатор shell. Скачайте скрипт, изучите его содержимое, а затем запустите.

curl -sLo yabs.sh https://raw.githubusercontent.com/masonr/yet-another-bench-script/master/yabs.sh
less yabs.sh
bash yabs.sh

Флаги указываются после -s -- при передаче через конвейер или сразу после имени файла при запуске локальной копии. Полезные флаги: -f пропускает тест диска, -i пропускает сетевой тест, -g пропускает Geekbench, -r сокращает количество локаций iperf3 до трех, -j выводит результаты в формате JSON, а -w results.json записывает этот JSON в файл.

bash yabs.sh -r -w yabs-run1.json

Две вещи, которые нужно знать перед первым запуском. Geekbench загружает результат и выдает публичную ссылку на browser.geekbench.com, поэтому любой, у кого есть эта ссылка, сможет увидеть модель вашего процессора и баллы. -g полностью пропускает этот тест. Во-вторых, этап iperf3 генерирует реальный трафик к серверам в разных регионах, что расходует ваш месячный лимит пропускной способности. На канале 1 Gbit/s полный сетевой тест может передать десятки гигабайт, поэтому используйте -r при небольшом лимите и -i на тарифах с оплатой за трафик.

Что означают показатели вывода yabs

В разделе disk запускается утилита fio с соотношением чтения и записи 50/50 для четырех размеров блоков: 4k, 64k, 512k и 1m. Для каждого из них отображаются IOPS (количество операций ввода-вывода в секунду) и пропускная способность. Строка 4k наиболее важна для баз данных, почтовых серверов и любых других задач с большим количеством мелких операций записи, так как основная часть серверного ввода-вывода состоит из небольших разрозненных блоков. Строка 1m актуальна для резервного копирования и работы с видео, где передаются значительные объемы данных.

В разделе network выполняется тестирование iperf3 с публичными серверами в различных регионах в обоих направлениях с использованием параллельных потоков. Низкие показатели здесь следует воспринимать как повод для проверки, а не как окончательный результат, так как публичные серверы iperf3 являются общими и часто перегружены, поэтому низкая скорость может быть вызвана проблемами на стороне удаленного узла.

Раздел Geekbench содержит оценки производительности для одного ядра и для многоядерного режима. Оценка для одного ядра показывает скорость выполнения одиночного запроса, компиляции или выполнения команды. Многоядерная оценка в основном отражает реальное количество доступных ядер процессора.

Диск: самостоятельный запуск fio

fio (flexible IO tester) — это инструмент, который лежит в основе раздела дисковых тестов yabs, и именно при прямом его использовании флаги начинают иметь значение.

sudo apt update && sudo apt install -y fio sysbench iperf3

Тест случайного чтения блоками 4k с глубиной очереди 32 на файловой системе, которая вас интересует:

fio --name=randread4k --filename=./fio-testfile --size=2G --bs=4k \
  --rw=randread --ioengine=libaio --iodepth=32 --direct=1 \
  --runtime=60 --time_based --group_reporting

Итоговая строка, которую нужно найти в выводе, выглядит следующим образом.

read: IOPS=184k, BW=719MiB/s (754MB/s)(42.1GiB/60001msec)

Ниже fio выводит блок clat percentiles. Значение 99.00-го перцентиля — это показатель, на который стоит ориентироваться, так как он отражает время ожидания самого медленного запроса из ста. Средняя задержка скрывает именно те задержки, которые замечает пользователь.

  • --direct=1 открывает файл с флагом O_DIRECT, поэтому операции чтения обходят кэш страниц ядра. Без этого параметра второй проход по файлу размером 2G на машине с 8G оперативной памяти будет выполнен из памяти, и fio покажет миллионы IOPS. Это число реально, но оно характеризует производительность памяти, а не диска.
  • --ioengine=libaio отправляет асинхронные запросы, что позволяет --iodepth=32 поддерживать 32 запроса в очереди одновременно. При использовании синхронного движка, такого как psync, значение iodepth выше 1 не дает никакого эффекта, и вы будете измерять только один запрос за раз.
  • --time_based --runtime=60 запускает тест на фиксированные 60 секунд вместо выполнения фиксированного объема работы, поэтому быстрый и медленный диски работают одинаковое время, что делает сравнение корректным.
  • --size=2G задает размер тестового файла. Убедитесь, что он больше любого кэша на пути прохождения данных, и предварительно проверьте наличие свободного места.

Тест случайной записи выполняется той же командой с флагом --rw=randwrite. Запускайте его отдельно, а затем удалите файл.

fio --name=randwrite4k --filename=./fio-testfile --size=2G --bs=4k \
  --rw=randwrite --ioengine=libaio --iodepth=32 --direct=1 \
  --runtime=60 --time_based --group_reporting
rm -f ./fio-testfile

Для нагрузки, более приближенной к реальному трафику, используйте --rw=randrw --rwmixread=70. Тип хранилища, на котором вы работаете, влияет на результаты сильнее, чем любой флаг, и это различие описано в разнице между NVMe и SATA SSD на VPS.

Когда fio завершается с ошибкой Unknown error -1

Прямой ввод-вывод (Direct IO) доступен не во всех файловых системах, поэтому если fio завершается с ошибкой при первом же запросе с установленным --direct=1, в первую очередь следует исключить проблемы с Direct IO. Ошибка может выглядеть так:

fio: io_u error on file ./fio-testfile: Unknown error -1: read offset=0, buflen=4096
fio: pid=1234, err=-1/file:ioengines.c:321, func=get_events, error=Unknown error -1

Сначала выполните df -hT .. Сама по себе Type типа overlay, которую Docker по умолчанию предоставляет контейнеру, не является причиной проблемы. overlayfs передает O_DIRECT нижележащей файловой системе и отклоняет запрос только в том случае, если эта система не поддерживает Direct IO, поэтому --direct=1 --ioengine=libaio работает с overlay, развернутой поверх ext4 или xfs. Если файловая система, на которой находится тестовый файл, действительно не поддерживает Direct IO, fio обычно сообщает об этом при открытии файла: fio: looks like your file system does not support direct=1/buffered=0. В этом случае укажите --filename путь к реальному локальному хранилищу, например, к bind-монтируемому тому, или запустите fio на хосте вместо контейнера. Если доступ к реальному хранилищу невозможен, буферизированный синхронный запуск как минимум подтвердит корректность самой команды.

fio --name=randread4k-buffered --filename=./fio-testfile --size=256M --bs=4k \
  --rw=randread --ioengine=psync --direct=0 --numjobs=1 \
  --runtime=15 --time_based --group_reporting
rm -f ./fio-testfile

Будьте честны в отношении того, что представляет собой этот запуск. После первого прохода файл размером 256M остается в page cache, поэтому показатель IOPS будет характеризовать вашу оперативную память. Используйте этот запуск, чтобы убедиться, что fio установлена и флаги интерпретируются верно. Никогда не приводите эти данные в качестве результатов тестирования диска.

Почему dd не является инструментом для тестирования производительности диска

dd часто встречается в обсуждениях VPS, но этот инструмент отвечает лишь на один узкий вопрос.

dd if=/dev/zero of=./ddtest bs=1M count=1024 oflag=direct conv=fdatasync
rm -f ./ddtest

Эта команда измеряет пропускную способность последовательной записи при использовании одного потока и одного запроса в очереди. Это приемлемый способ для базовой проверки работоспособности системы. Команда ничего не говорит о случайном вводе-выводе (random IO) и о том, как система поведет себя при поступлении 32 запросов одновременно. Уберите oflag=direct, и запись пойдет через page cache, но conv=fdatasync всё равно заставит систему сбросить данные на накопитель до завершения работы команды. Если убрать и этот параметр, результат будет в основном показывать скорость, с которой ядро принимает данные в оперативную память. Именно поэтому показатели dd, которые часто приводят на форумах, нередко выглядят абсурдно.

CPU: sysbench cpu

sysbench cpu --cpu-max-prime=20000 --threads=1 run
sysbench cpu --cpu-max-prime=20000 --threads=$(nproc) run

Ключевым показателем является events per second. Сначала запустите тест в однопоточном режиме. Это число определяет скорость выполнения одного PHP-запроса или завершения задачи компиляции; оно сильнее всего различается у хостов в одной ценовой категории. Затем запустите тест с использованием всех потоков: это покажет, как пропускная способность масштабируется по всем выделенным vCPU.

Чётко понимайте, что именно измеряет этот тест: sysbench cpu многократно находит простые числа методом пробного деления. Для каждого кандидата вычисляется квадратный корень с двойной точностью, затем выполняются проверки делителей с использованием 64-битного целочисленного деления по модулю, при этом каждый делитель сравнивается с полученным пределом с плавающей запятой. Таким образом, тест сочетает целочисленные вычисления и операции с плавающей запятой. Он не нагружает пропускную способность памяти, векторные блоки или кэш каким-либо образом, напоминающим реальную рабочую нагрузку. Поэтому он подходит для сравнения двух хостов, но плохо предсказывает производительность вашего приложения.

В Ubuntu 24.04 поставляется sysbench 1.0.20, где имя теста указывается первым. Если вы скопируете команду с --test=cpu из старой статьи, вы получите WARNING: the --test option is deprecated. Результаты sysbench 0.4 и sysbench 1.0 совершенно несопоставимы, поэтому никогда не сравнивайте свои показатели с опубликованными данными, если в них не указана версия программы.

Память: sysbench memory

sysbench memory --memory-block-size=1M --memory-total-size=20G --memory-oper=write --threads=1 run
sysbench memory --memory-block-size=1M --memory-total-size=20G --memory-oper=read --threads=1 run

Результат измеряется в MiB/сек. Оставляйте значение --memory-block-size равным 1M и используйте его неизменным для всех сравниваемых хостов. При 1K показатели резко падают, так как накладные расходы на каждую операцию возрастают в тысячу раз, и в итоге вы измеряете стоимость цикла, а не пропускную способность памяти. Это самый часто неверно задаваемый флаг в опубликованных результатах тестирования памяти.

Сеть: iperf3

Честный способ протестировать пропускную способность — использовать вторую машину под вашим контролем, так как вы будете знать, что происходит на обоих концах.

На удаленной стороне:

iperf3 -s

Эта команда запускает прослушивание на TCP-порту 5201. Открывайте порт только для того адреса, с которого проводите тестирование, и закрывайте его после завершения. Базовые правила брандмауэра ufw на VPS описывают синтаксис.

С тестируемого VPS:

iperf3 -c 203.0.113.10 -t 30
iperf3 -c 203.0.113.10 -t 30 -R
iperf3 -c 203.0.113.10 -t 30 -P 8

Первая команда измеряет скорость передачи данных (upload) с тестируемой машины. Флаг -R меняет направление, что позволяет измерить скорость загрузки (download). Флаг -P 8 открывает восемь параллельных потоков.

Запускайте как одиночный поток, так и параллельную версию, так как они отвечают на разные вопросы. Одно TCP-соединение может удерживать лишь столько неподтвержденных данных, сколько позволяет его окно, поэтому его предел примерно равен размеру окна, деленному на время кругового обхода (RTT). При задержке 80 мс и окне 4 MB этот предел составляет около 400 Mbit/s, независимо от реальной скорости канала. Показатель одиночного потока говорит о том, какую скорость получит одна загрузка. Параллельный показатель говорит о полной емкости канала.

Следите за лимитом трафика во время тестирования. Тридцать секунд на скорости 1 Gbit/s передают около 3.75 GB, а вы будете запускать тест несколько раз в каждом направлении.

Эталонные показатели и их интерпретация

ГрафикTypical published 4k random read IOPS by storage class
Данные, на которых построен график
[
  {
    "device": "Local NVMe",
    "iops_4k_read": "180,000"
  },
  {
    "device": "Local SATA SSD",
    "iops_4k_read": "90,000"
  },
  {
    "device": "Network block",
    "iops_4k_read": "12,000"
  },
  {
    "device": "Spinning disk",
    "iops_4k_read": "180"
  }
]

Локальный NVMe-том в опубликованных результатах обычно демонстрирует около 180,000 IOPS при случайном чтении блоками по 4k. Локальный SATA SSD выдает около 90,000. Сетевое блочное хранилище, где каждый запрос проходит через сеть перед записью на диск, находится в районе 12,000, а обычный жесткий диск (HDD) справляется примерно с 180, так как для каждого случайного запроса требуется физическое перемещение считывающей головки.

Это типичные заявленные показатели для каждого класса хранилищ, а не измерения с одного конкретного хоста. Используйте их только для одной цели: проверки того, что ваш результат находится в правильном порядке величин. Если тариф, продаваемый как NVMe, показывает в тестах производительности лишь несколько тысяч IOPS при чтении 4k, сначала убедитесь, что --direct=1 был включен. Если это так, проверьте лимиты IOPS и кредиты на кратковременное ускорение (burst credits) для данного тарифа, а также наличие конкуренции за ресурсы хранилища и заявленные характеристики оборудования.

Почему один запуск не является бенчмарком

Единичный результат — это моментальный снимок состояния системы в конкретную минуту на разделяемом оборудовании. Рассматривайте его как одну выборку.

  • Выполняйте каждый тест не менее пяти раз в разное время суток и как минимум в течение двух разных дней. Фиксируйте медиану и разброс значений. Результат, опубликованный без указания разброса, является маркетинговой цифрой.
  • Записывайте время ожидания ресурсов (steal time) для каждого запуска. Сохраняйте результаты, где st было высоким, и исследуйте, отражают ли они конкуренцию за ресурсы или квоту CPU тарифного плана; отбрасывание таких данных может скрыть реальную производительность, которую вы получаете.
  • Запускайте дисковый тест с двумя разными длительностями. Многие тарифные планы предоставляют лимит burst IOPS, который восстанавливается со временем, но ни 60-секундный запуск fio, ни --runtime=600 не гарантируют, что вы измерили базовую производительность. Кредиты AWS gp2 могут поддерживать 3,000 IOPS в течение как минимум 30 минут при полном балансе, поэтому оба запуска могут измерять только производительность в режиме burst. Изучите модель кредитования провайдера и отслеживайте баланс кредитов, прежде чем называть результат устойчивой производительностью.
  • Убедитесь, что никакие другие процессы не запущены. unattended-upgrades запуск транзакции apt в середине теста CPU отнимает реальные баллы, а ps -e -o comm= | grep -E 'apt|dpkg' перед каждым запуском занимает секунду.
  • Изменяйте только одну переменную за раз. Разные версии инструментов, размеры блоков или количество потоков дают числа, которые нельзя сравнивать, независимо от того, насколько похожими они выглядят.

При сравнении двух провайдеров проводите тесты в один и тот же час одного и того же дня. В противном случае вы измеряете влияние времени суток.

Тестируйте собственную нагрузку в последнюю очередь

Синтетические инструменты ранжируют машины. Только ваша собственная рабочая нагрузка покажет, достаточно ли производительности сервера. Замеряйте время выполнения тех задач, которые вы решаете на самом деле.

time tar -czf /tmp/bench.tgz /usr/share
rm -f /tmp/bench.tgz

Эта команда сжимает несколько сотен мегабайт, поэтому она нагружает одновременно CPU и диск, реагируя на изменения в любом из них. Предупреждение Removing leading / from member names является нормальным. Еще лучше замерить время вашей собственной сборки, самого медленного запроса к базе данных или отрисовки страницы. Если сборка на одном хосте занимает 4 минуты, а на другом 7, вопрос решен, независимо от результатов Geekbench. Это измерение также позволяет понять, в какой момент дальнейшее увеличение мощности перестает окупаться. Это стоит знать до того, как вы изучите сколько на самом деле стоит VPS в месяц или перенесете нагрузку на выделенный сервер.

FAQ

Почему результаты тестов производительности каждый раз разные?

VPS делит физический процессор, хранилище и сеть с другими арендаторами, поэтому результат зависит от их текущей активности. Запустите vmstat 1 во время теста и изучите столбец st: показатель steal time фиксирует недоступное процессорное время, но он может отражать как ограничение провайдером выделенных вам ресурсов, так и общую нагрузку на хост. Значение выше 5% не указывает на конкретную причину. Решение заключается в методологии, а не в настройке параметров. Выполните каждый тест пять и более раз в разное время суток, затем укажите медианное значение вместе с разбросом.

Почему fio показывает миллионы IOPS?

Почти всегда из-за отсутствия --direct=1. Без этого параметра fio читает данные через page cache ядра, поэтому после первого прохода тестовый файл размером 2G отдается из оперативной памяти, и вы измеряете пропускную способность памяти. Добавьте --direct=1 и следите, чтобы размер тестового файла превышал объем любого кэша на пути данных. Если после этого --direct=1 завершается с ошибкой, запустите df -hT . и проверьте, на каком носителе находится тестовый файл. Тип overlay сам по себе не является проблемой, так как overlayfs передает O_DIRECT нижележащему хранилищу. Переносите тестовый файл на реальный локальный диск только в том случае, если нижележащая файловая система не поддерживает direct IO.

Достаточно ли одного yabs.sh?

Для первичной оценки — да. Он запускает fio с четырьмя размерами блоков, iperf3 в обоих направлениях и Geekbench, а также выводит сводную информацию, понятную другим пользователям. Его становится недостаточно, когда нужно понять причину конкретного значения, так как вы не можете менять его флаги для каждого теста. Если результат yabs выглядит некорректно, воспроизведите его напрямую через fio или sysbench, изменяя по одному флагу за раз.

Какое одно число предсказывает быстродействие моего приложения?

Для большинства веб-приложений и баз данных это скорость одного ядра процессора и задержка при случайном чтении блоками 4k, именно в таком порядке. Показатели пропускной способности выглядят внушительно, но редко на что-то влияют, так как типичный запрос имеет малый размер. Используйте 99-й перцентиль из блока clat percentiles в fio, а не среднее значение, так как именно один медленный запрос из ста замечает пользователь.

Нужно ли что-то устанавливать перед тестированием?

fio, sysbench и iperf3 есть в репозиториях Ubuntu и Debian: sudo apt install -y fio sysbench iperf3. yabs.sh работает в Bash и требует curl или wget для загрузки данных, а также tar для распаковки Geekbench; без tar тест Geekbench будет пропущен. Скрипт использует установленные в системе fio и iperf3, а при их отсутствии скачивает статические бинарные файлы. Удаляйте все тестовые файлы после завершения работы, так как файл fio размером 2G, оставленный на диске объемом 20G, через несколько недель станет причиной уведомления о нехватке места у кого-то из администраторов.

Была ли эта статья полезной?

#benchmarks#fio#sysbench#yabs#iperf3#vps-performance