Цифры «до 3000 МБ/с» в описании тарифа ничего не говорят о том, как диск поведёт себя под вашей базой данных. Единственный честный способ узнать реальную производительность хранилища — нагрузить его инструментом fio и посмотреть на IOPS и латентность, а не на красивый мегабайтный поток. В этой статье разберём, как установить fio, какие профили нагрузки запускать на VPS и как интерпретировать результаты, чтобы отличить настоящий NVMe от узкого места.
Почему dd и hdparm не подходят
Первое, что делает большинство после покупки сервера — запускает dd if=/dev/zero of=test bs=1G count=1. Проблема в том, что такой тест измеряет последовательную запись одним потоком, да ещё и часто проходит через кеш файловой системы. Реальные приложения — базы данных, веб-серверы, очереди — работают иначе: они читают и пишут мелкими блоками по 4–16 КБ в случайные места диска, причём параллельно.
hdparm -t ещё дальше от реальности: он измеряет только линейное чтение с устройства в обход файловой системы. На таких тестах даже старый SATA SSD выглядит прилично, а разница с NVMe почти незаметна. Зато на случайном чтении 4К-блоками с глубокой очередью NVMe уходит в отрыв на порядок — именно это мы и будем измерять. Подробнее о том, почему архитектура NVMe даёт такой выигрыш, читайте в статье что такое NVMe в VPS.
Установка fio
fio есть в репозиториях всех популярных дистрибутивов:
# Debian / Ubuntu
apt update && apt install -y fio
# CentOS / AlmaLinux / Rocky
dnf install -y fio
# Проверяем версию
fio --version
Тесты запускайте в каталоге на том диске, который хотите проверить. Убедитесь, что свободно хотя бы 5–10 ГБ: fio создаст тестовый файл, и если он окажется меньше объёма RAM, часть чтений уйдёт в кеш и результаты будут завышены.
Ключевые параметры fio
Прежде чем копировать команды, полезно понимать, что означает каждый флаг:
| Параметр | Что задаёт | Типичное значение |
|---|---|---|
--rw | Тип нагрузки: randread, randwrite, read, write, randrw | зависит от теста |
--bs | Размер блока | 4k для БД, 1M для потоковых операций |
--iodepth | Глубина очереди запросов | 1 — латентность, 32–64 — пропускная способность |
--numjobs | Число параллельных потоков | 1–4 |
--size | Размер тестового файла | 4G и больше |
--runtime | Длительность теста в секундах | 60 |
--direct | Обход страничного кеша (O_DIRECT) | всегда 1 |
--ioengine | Механизм ввода-вывода | libaio |
Параметр --direct=1 критичен: без него вы измерите скорость оперативной памяти, а не диска.
Тест 1: случайное чтение 4К (главный тест для БД)
Это профиль нагрузки MySQL, PostgreSQL, MongoDB — мелкие случайные чтения:
fio --name=randread --ioengine=libaio --rw=randread \
--bs=4k --iodepth=64 --numjobs=1 --size=4G \
--runtime=60 --time_based --direct=1 --group_reporting
В выводе ищите строку вида:
read: IOPS=48.2k, BW=188MiB/s (198MB/s)
Здесь важны именно IOPS, а не мегабайты. 48 тысяч операций в секунду — типичный результат для NVMe; SATA SSD в тех же условиях покажет 15–25 тысяч, а HDD — жалкие 100–200.
Тест 2: случайная запись 4К
fio --name=randwrite --ioengine=libaio --rw=randwrite \
--bs=4k --iodepth=64 --numjobs=1 --size=4G \
--runtime=60 --time_based --direct=1 --group_reporting
Запись почти всегда медленнее чтения — это нормально. Насторожить должна не сама цифра, а её нестабильность: если IOPS скачут от 40 тысяч до 2 тысяч в рамках одного минутного прогона, значит хранилище хоста перегружено соседями или упирается в лимиты.
Тест 3: последовательное чтение и запись
Этот профиль важен для бэкапов, раздачи больших файлов и копирования данных:
# Последовательное чтение крупными блоками
fio --name=seqread --ioengine=libaio --rw=read \
--bs=1M --iodepth=16 --numjobs=1 --size=4G \
--runtime=60 --time_based --direct=1 --group_reporting
# Последовательная запись
fio --name=seqwrite --ioengine=libaio --rw=write \
--bs=1M --iodepth=16 --numjobs=1 --size=4G \
--runtime=60 --time_based --direct=1 --group_reporting
Здесь уже смотрим на BW (bandwidth): NVMe обычно выдаёт от 1000 МБ/с и выше, SATA SSD упирается в потолок интерфейса около 500–550 МБ/с.
Тест 4: смешанная нагрузка 70/30
Ближе всего к жизни веб-проекта — смесь чтения и записи:
fio --name=mixed --ioengine=libaio --rw=randrw --rwmixread=70 \
--bs=4k --iodepth=32 --numjobs=2 --size=4G \
--runtime=60 --time_based --direct=1 --group_reporting
fio покажет отдельные секции для чтения и записи. Если под смешанной нагрузкой чтение проседает в разы сильнее, чем в чистом тесте, — диск плохо справляется с конкуренцией, и под нагруженной базой это аукнется.
Тест 5: латентность одиночного запроса
Глубокая очередь скрывает задержки, поэтому латентность меряют с iodepth=1:
fio --name=latency --ioengine=libaio --rw=randread \
--bs=4k --iodepth=1 --numjobs=1 --size=1G \
--runtime=30 --time_based --direct=1 --group_reporting
Смотрите на блок clat percentiles. Значение p99 показывает, что 99% запросов выполнились быстрее этой отметки:
clat percentiles (usec):
| 99.00th=[ 250], 99.90th=[ 400], 99.99th=[ 900]
Для NVMe нормальный p99 — десятки-сотни микросекунд. Если p99 уходит в миллисекунды, а p99.9 — в десятки миллисекунд, ваши SQL-запросы будут периодически «подвисать», хотя средние показатели останутся красивыми.
Как читать результаты: ориентиры
| Показатель (4k, iodepth=64) | HDD | SATA SSD | NVMe |
|---|---|---|---|
| Случайное чтение, IOPS | 100–200 | 15–25 тыс. | 40–200 тыс. |
| Случайная запись, IOPS | 100–150 | 10–20 тыс. | 30–100 тыс. |
| Латентность p99 (iodepth=1) | 10–30 мс | 0,3–1 мс | 0,05–0,5 мс |
| Линейное чтение, МБ/с | 100–200 | 450–550 | 1000+ |
Конкретные цифры на VPS зависят от лимитов виртуализации и нагрузки на узел, поэтому важнее абсолютных значений — стабильность: прогоните тест три раза в разное время суток и сравните разброс. Если хотите оценить сервер целиком, а не только диск, пригодится наш гайд как протестировать VPS: бенчмарки, а процессор отдельно проверяется через sysbench.
Типичные ошибки при тестировании
Маленький тестовый файл. --size=256M при 8 ГБ RAM — почти гарантия, что данные осядут в кеше. Делайте файл минимум 4 ГБ, а лучше в половину объёма памяти и больше.
**Забытый --direct=1.** Без него результаты в разы выше реальных — вы тестируете page cache.
Тест на «холодном» сервере и выводы навсегда. Дисковая подсистема VPS — общий ресурс. Один замер в 4 утра воскресенья не показателен; повторите в будний вечер.
Запуск на боевом сервере под нагрузкой. fio с iodepth=64 сам создаёт серьёзную нагрузку и замедлит ваши приложения. Тестируйте до ввода в продакшен или в окно обслуживания. После тестов не забудьте удалить файлы randread.0.0, seqwrite.0.0 и подобные.
Игнорирование steal и swap. Медленный «диск» иногда оказывается перегруженным CPU или свопом. Проверьте vmstat 1 во время теста; про настройку подкачки читайте в статье настройка swap на VPS.
Частые вопросы
Сколько времени занимает полный тест диска?
Пять описанных профилей по 30–60 секунд каждый — около 5 минут чистого времени. Для надёжных выводов повторите серию 2–3 раза в разное время суток, чтобы исключить влияние временной нагрузки на гипервизоре. Итого адекватная оценка диска занимает один день с тремя короткими сессиями.
Может ли fio испортить SSD или данные на сервере?
Данные — нет, если вы запускаете fio с параметром --name в отдельном каталоге: он работает с собственными тестовыми файлами и не трогает чужие. Никогда не указывайте --filename=/dev/vda на живом сервере — прямой тест блочного устройства с записью уничтожит файловую систему. Что касается ресурса SSD, разовые тесты записывают десятки гигабайт — это капля на фоне ресурса современных накопителей.
Почему мои IOPS ниже, чем в обзорах «голых» NVMe-дисков?
На VPS между вами и диском находится слой виртуализации, а сам накопитель делится между клиентами, поэтому провайдеры ограничивают IOPS на виртуальную машину. Это нормально: важно, чтобы лимит с запасом покрывал вашу нагрузку и держался стабильно. Типичному сайту с базой данных достаточно 5–10 тысяч IOPS, так что даже «урезанный» NVMe даёт многократный запас.
Какой один тест запустить, если нет времени на все?
Случайное чтение 4К с iodepth=64 (тест 1) плюс взгляд на латентность p99 из теста 5. Эти два числа описывают 90% реальных сценариев: первое — потолок производительности под нагрузкой, второе — отзывчивость в спокойном режиме. Линейные мегабайты в секунду наименее информативны, хотя именно их чаще всего публикуют в рекламе.
Что делать, если результаты стабильно плохие?
Сначала исключите свои факторы: тест с --direct=1, файл больше RAM, сервер без посторонней нагрузки, отсутствие CPU steal. Если после этого случайное чтение 4К выдаёт уровень HDD (сотни IOPS) на тарифе с заявленным SSD/NVMe — это предмет для тикета в поддержку с приложенным выводом fio. Аргументированный тикет с цифрами решается быстрее, чем жалоба «всё тормозит».
Проверьте на настоящем NVMe
Лучший способ прочувствовать разницу — прогнать эти команды на быстром сервере. VPS Pro от Cheap-Host — 12 vCPU, 16 ГБ RAM и 128 ГБ NVMe в Москве за 750 ₽/мес: хватит и для теста, и для нагруженного проекта. Сервер выдаётся за 45–60 секунд — закажите на https://cheap-host.onl/ и проверьте цифры сами.