Як правильно протестувати VPS: yabs.sh, fio, sysbench
Запустіть yabs.sh, а потім fio, sysbench та iperf3 вручну: пояснюємо значення результатів і чому один тест VPS майже нічого не доводить.
Що означає бенчмаркінг VPS
Щоб виконати бенчмаркінг VPS, вимірюють чотири показники: швидкість роботи одного ядра CPU, пропускну здатність пам’яті, кількість малих випадкових дискових операцій, які сховище обробляє за секунду, і пропускну здатність мережевого каналу. Один запуск yabs.sh дає всі чотири показники приблизно за десять хвилин. Правильно інтерпретувати результат складніше, оскільки VPS (віртуальний приватний сервер) використовує фізичне обладнання спільно з іншими орендарями. Тому той самий сервер може показати один результат о 03:00 і зовсім інший о 20:00.
Спочатку запустіть yabs.sh, щоб швидко оцінити систему, а потім вручну запустіть інструменти, які він використовує. Самостійний запуск дає змогу змінити один прапорець, простежити, як змінюється показник, і зрозуміти, що саме він вимірює. Виконуйте це після налаштування сервера, а не до нього. Спочатку виконайте кроки з розділу перші десять хвилин на новому VPS, оскільки сервер, який ще встановлює перший набір оновлень, дає неточні результати бенчмаркінгу з причин, не пов’язаних з обладнанням.
Перевірте машину, перш ніж її вимірювати
Половина кожного невдалого бенчмарку — це машина, яку автор не розумів.
nproc
lscpu | grep -E 'Model name|Hypervisor|Thread'
free -h
df -hT /
uname -r
systemd-detect-virtHypervisor vendor: KVM означає повну віртуалізацію, тому ви запускаєте власне ядро. Виведення systemd-detect-virt, у якому є lxc або openvz, натомість означає контейнерну віртуалізацію: ви використовуєте спільне ядро хоста, а обмеження CPU та пам’яті задаються параметрами cgroup (control group), а не віртуальним обладнанням. У системі з cgroup v2 ліміт CPU можна прочитати безпосередньо.
cat /sys/fs/cgroup/cpu.maxmax 100000 означає, що квоти немає. 200000 100000 означає, що можна використовувати 200000 мікросекунд CPU у кожному періоді тривалістю 100000 мікросекунд, тобто квоту, еквівалентну двом ядрам. План, заявлений як 4 vCPU, але з квотою у два ядра, ніколи не покаже результатів на рівні чотирьох ядер, і жоден інструмент бенчмаркінгу не виведе рядок із поясненням причини.
df -hT / важливий з іншої причини: через стовпець Type. Якщо в ньому зазначено overlay, ви перебуваєте всередині контейнера, і тест диска нижче потребує змін. Зафіксуйте це зараз.
Постійно контролюйте steal time
Steal time — це частка часу, протягом якого ваш віртуальний CPU був готовий виконуватися, але гіпервізор передав фізичне ядро іншому користувачу. Це найкорисніший окремий показник, який дає змогу визначити, що причина результату пов’язана із сусідніми віртуальними машинами, а не з апаратним забезпеченням.
vmstat 1 10Праворуч переглядайте стовпчик st. Стабільне значення 0 або 1 є нормальним. Тривалі значення понад 5 означають, що в цей момент на хості бракує ресурсів через надмірну кількість віртуальних машин. Тому всі зафіксовані в цей період показники CPU будуть заниженими не з вини вашої машини. top показує те саме значення, що й %st у рядку CPU. Під час тестування продуктивності залиште vmstat 1 запущеним у другій SSH-сесії та записуйте значення steal поруч із кожним результатом.
Почніть із yabs.sh
yabs.sh (Yet Another Bench Script) — це shell-скрипт, який завантажує статичні бінарні файли fio, iperf3 і Geekbench, запускає їх і виводить один підсумковий результат. Це стандартний формат для обговорення результатів тестування 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Під час передавання через pipe прапори вказують після -s --, а під час запуску локальної копії — безпосередньо після імені файлу. Корисні прапори: -f пропускає тест диска, -i пропускає мережевий тест, -g пропускає Geekbench, -r скорочує кількість локацій iperf3 до двох, -j виводить результати у форматі JSON, а -w results.json записує цей JSON у файл.
bash yabs.sh -r -w yabs-run1.jsonПеред першим запуском потрібно знати дві речі. Geekbench завантажує результати й виводить публічний URL на browser.geekbench.com, тому будь-хто, хто має це посилання, може переглянути модель CPU та результати тестів. -g повністю пропускає цей тест. По-друге, етап iperf3 передає реальний мережевий трафік на сервери в кількох регіонах, і цей трафік враховується у вашому щомісячному ліміті. У каналі зі швидкістю 1 Gbit/s повний мережевий етап може передати десятки гігабайтів, тому за малого ліміту використовуйте -r, а в мережі з тарифікацією за обсягом — -i.
Що означає кожна частина виводу yabs
Розділ диска запускає fio зі співвідношенням читання та запису 50/50 для чотирьох розмірів блоків: 4k, 64k, 512k і 1m. Для кожного розміру він показує IOPS (операції вводу-виводу за секунду) і пропускну здатність. Для бази даних, поштового сервера або будь-якого сервісу, який виконує багато малих операцій запису, важливий рядок 4k, оскільки більшість серверних операцій вводу-виводу мають малий і розрізнений характер. Рядок 1m важливий для резервного копіювання та роботи з відео, коли передаються довгі послідовності байтів.
Розділ мережі запускає iperf3 проти публічних серверів у кількох регіонах і перевіряє передавання в обох напрямках із використанням паралельних потоків. Сприймайте низький показник як привід для додаткової перевірки, а не як остаточний висновок, оскільки публічні сервери iperf3 є спільними для багатьох користувачів і часто перевантажені. Тому низький результат може бути спричинений віддаленою стороною.
Розділ Geekbench містить оцінку продуктивності одного ядра та оцінку багатоядерної продуктивності. Показник одного ядра прогнозує, як швидко завершиться один запит, одна компіляція або один запит до бази даних. Багатоядерний показник переважно показує, скільки ядер ви фактично отримали.
Disk: запустіть 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
Прямий доступ до диска доступний не в кожній файловій системі. overlay, файлова система, яку Docker типово надає контейнеру, і кілька мережевих файлових систем не підтримують O_DIRECT, тому libaio передає запит, який ядро не може виконати, і fio припиняє роботу:
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, укажіть для --filename шлях до сховища з реальним диском, наприклад до bind mounted volume, або запустіть 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 залишається в кеші сторінок, тому показник IOPS описує швидкодію RAM. Використовуйте цей запуск, щоб підтвердити, що fio встановлено, а параметри розібрано без помилок. Ніколи не наводьте цей результат як результат тестування диска.
Чому dd не є тестом продуктивності диска
dd часто використовують в обговореннях VPS, але ця команда відповідає лише на одне вузьке запитання.
dd if=/dev/zero of=./ddtest bs=1M count=1024 oflag=direct conv=fdatasync
rm -f ./ddtestЦе вимірює пропускну здатність послідовного запису в одному потоці та з одним запитом у черзі. Це прийнятна базова перевірка. Вона нічого не говорить про випадкові операції введення-виведення та про те, що відбувається, коли одночасно надходить 32 запити. Якщо прибрати oflag=direct, вимірювання здебільшого показує, наскільки швидко ядро приймає записи в пам’ять. Саме тому наведені на форумах значення 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/sec. На кожній машині швидкість читання вища за швидкість запису. Залишайте --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Перша команда вимірює вихідну швидкість із машини, яку тестуєте. -R змінює напрямок і вимірює вхідну швидкість. -P 8 відкриває вісім паралельних потоків.
Виконайте тест як з одним потоком, так і в паралельному режимі. Ці результати відповідають на різні запитання. Одне TCP-з’єднання може передати лише такий обсяг непідтверджених даних, який дозволяє його вікно. Тому його гранична швидкість приблизно дорівнює розміру вікна, поділеному на час проходження сигналу туди й назад. За затримки 80 ms і вікна 4 MB ця межа становить приблизно 400 Mbit/s, незалежно від фактичної швидкості каналу. Показник для одного потоку показує, яку швидкість отримає одне завантаження. Показник для паралельних потоків показує пропускну здатність каналу.
Під час тестування стежте за доступним обсягом трафіку. За 30 секунд на швидкості 1 Gbit/s передається приблизно 3.75 GB, а тест потрібно буде виконати кілька разів у кожному напрямку.
Довідкові показники та їх інтерпретація
The data behind this chart
[
{
"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. Якщо так, то або сховище не відповідає опису на сторінці продукту, або ви використовуєте його спільно з дуже завантаженим сусідом.
Чому один запуск не є бенчмарком
Один результат — це знімок однієї хвилини на спільній машині. Розглядайте його як одну вибірку.
- Запускайте кожен тест щонайменше п’ять разів у різні години та щонайменше у два різні дні. Зберігайте медіану та розкид. Результат без розкиду — це маркетинговий показник.
- Поруч із кожним запуском записуйте steal time. Відкидайте запуски, під час яких
stбуло високим, або щонайменше зазначайте це. - Запускайте тест диска з двома тривалостями. Багато тарифів надають burst allowance для IOPS, який з часом відновлюється, тому 60-секундний запуск fio вимірює burst, тоді як
--runtime=600вимірює мінімальну продуктивність. Саме її ви отримуєте у невдалий день. - Переконайтеся, що нічого іншого не працює.
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
Чому щоразу отримую інший результат benchmark?
VPS використовує фізичні CPU, сховище й мережу спільно з іншими клієнтами, тому результат залежить від того, що вони роблять у цей момент. Запустіть vmstat 1 під час тесту й перегляньте стовпець st: стабільне steal time понад 5 означає, що host був зайнятий, а показник CPU низький з причин, не пов’язаних із вашою машиною. Вирішення полягає не в tuning, а в методиці. Запустіть кожен тест щонайменше п’ять разів у різні години, а потім наведіть медіану разом із розкидом значень.
Чому fio показує мільйони IOPS?
Майже завжди тому, що відсутній --direct=1. Без нього fio читає через page cache ядра, тому після першого проходу тестовий файл розміром 2G обслуговується з RAM, і ви фактично вимірюєте пропускну здатність пам’яті. Додайте --direct=1 і використовуйте тестовий файл, більший за будь-який cache на шляху. Якщо --direct=1 завершується помилкою err=-1/file:ioengines.c:321, func=get_events, error=Unknown error -1, виконайте df -hT .: Type на overlay не підтримує O_DIRECT, тому спрямовуйте тест безпосередньо на реальне сховище.
Чи достатньо самого yabs.sh?
Для первинної оцінки — так. Він запускає fio з чотирма розмірами блоків, iperf3 в обох напрямках і Geekbench, а також виводить один підсумок, який можуть прочитати інші. Цього недостатньо, коли потрібно зрозуміти причину певного показника, оскільки не можна змінювати його flags окремо для кожного тесту. Якщо результат yabs виглядає неправильно, відтворіть тест безпосередньо через fio або sysbench і змінюйте по одному flag за раз.
Яке одне число найкраще прогнозує швидкодію мого застосунку?
Для більшості вебзастосунків і баз даних — швидкодія одного CPU core і latency випадкового читання 4k, саме в такому порядку. Показники throughput мають вражаючий вигляд, але рідко щось визначають, оскільки типовий запит невеликий. Наводьте 99-й percentile із блоку fio clat percentiles, а не середнє значення, оскільки саме один повільний запит зі ста помічає користувач.
Чи потрібно щось встановлювати перед benchmark?
fio, sysbench та iperf3 доступні в архівах Ubuntu і Debian: sudo apt install -y fio sysbench iperf3. Для yabs.sh потрібен лише curl, оскільки він завантажує static binaries для всього відсутнього. Після завершення видаліть усі тестові файли, оскільки залишений на диску 20G файл fio розміром 2G через кілька тижнів може спричинити alert про заповнення диска.