fio: тест реальной скорости NVMe-диска на VPS

Администрирование
fio: тест реальной скорости NVMe-диска на VPS

Цифры «до 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)HDDSATA SSDNVMe
Случайное чтение, IOPS100–20015–25 тыс.40–200 тыс.
Случайная запись, IOPS100–15010–20 тыс.30–100 тыс.
Латентность p99 (iodepth=1)10–30 мс0,3–1 мс0,05–0,5 мс
Линейное чтение, МБ/с100–200450–5501000+

Конкретные цифры на 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/ и проверьте цифры сами.

Читайте также