fio: как правильно тестировать скорость дисков
fio — стандартная утилита для нагрузочного тестирования дисков в Linux. Её используют, когда нужно понять, на что реально способен SSD, NVMe, HDD, RAID-массив, сетевой диск или том у облачного провайдера: сколько даёт последовательного чтения, как ведёт себя на случайных запросах, какая задержка на p95/p99, где начинается насыщение по очереди.
Главная проблема не в запуске fio, а в корректной методике. Один и тот же диск можно «разогнать» до красивых цифр за счёт page cache, маленького файла, неподходящего block size или слишком короткого теста. А можно случайно стереть данные, если запустить запись прямо по блочному устройству. Поэтому хороший тест диска в fio — это не одна команда из интернета, а понятный сценарий: что измеряем, какими параметрами и как читаем результат.
Ниже — практический подход для хостинга, VPS, выделенных серверов и баз данных: безопасные команды, типовые профили, расшифровка вывода и частые ошибки.
Что именно измеряет fio
fio генерирует дисковую нагрузку по заданному профилю и показывает, как подсистема хранения отвечает на эту нагрузку. В отличие от простого dd, он умеет моделировать разные типы I/O: последовательные и случайные операции, чтение и запись, смешанную нагрузку, несколько потоков, разные размеры блоков и глубину очереди.
Для дисков обычно смотрят не одну метрику, а набор:
1) Throughput — пропускная способность в MiB/s или MB/s. Важна для больших файлов, бэкапов, видеоконтента, логов, дампов баз. Последовательное чтение 1M блоками может дать сотни или тысячи мегабайт в секунду, но это не значит, что база данных будет работать так же быстро.
2) IOPS — количество операций ввода-вывода в секунду. Критично для случайного доступа: базы данных, очереди, почтовые серверы, мелкие файлы, контейнеры. Обычно измеряют на 4k, потому что это близко к размеру страницы памяти и частый ориентир для БД.
3) Latency — задержка операций. Для продакшена часто важнее не средняя задержка, а хвосты: p95, p99, p99.9. Диск может показывать хорошие IOPS, но иногда отвечать десятками или сотнями миллисекунд — такие всплески бьют по API и веб-приложениям.
4) Saturation — насыщение устройства: момент, когда увеличение iodepth или numjobs почти не повышает IOPS, зато резко растёт задержка. Именно здесь видно, сколько параллелизма диск выдерживает без деградации.
Если вы разбираете задержки сайта, fio стоит использовать вместе с системными метриками. Например, сначала посмотреть текущую дисковую активность через iostat и iotop, затем отдельно прогнать контролируемый тест. Для более глубокого разбора полезен материал про I/O latency и узкие места дисковой подсистемы.
Установка fio и безопасность тестов
На большинстве Linux-дистрибутивов fio ставится из стандартных репозиториев:
sudo apt update
sudo apt install fioДля RHEL-подобных систем:
sudo dnf install fioИли:
sudo yum install fioПроверить версию:
fio --versionПеред тестами решите, где именно запускать нагрузку: по файлу в файловой системе или напрямую по блочному устройству.
1) Тест по файлу безопаснее — вы указываете --filename=/mnt/test/fio.test или --directory=/mnt/test, и fio создаёт тестовый файл. Такой вариант подходит для VPS, обычных серверов, проверки тома с файловой системой, оценки поведения приложения на конкретном mount point.
2) Тест по блочному устройству опаснее — --filename=/dev/nvme0n1 или --filename=/dev/sdb. Любой тест записи по устройству может уничтожить данные. Такой режим используют на пустых дисках перед вводом в эксплуатацию, на стендах или после полного бэкапа.
3) Не тестируйте продакшен в пиковое время — fio способен занять диск полностью. На сервере с базой данных это приведёт к росту latency, очередям запросов и ошибкам приложения. Если тест всё же нужен на живой системе, ограничивайте runtime, размер файла, интенсивность и следите за метриками.
4) Не верьте тесту на маленьком файле — если файл помещается в RAM, результат может отражать скорость памяти и page cache, а не диска. Размер тестового файла должен быть больше доступной памяти или используйте --direct=1.
Для тестов записи на важных системах сначала убедитесь, что бэкапы действительно есть и восстанавливаются. Если речь о базах, пригодятся материалы про резервное копирование PostgreSQL и виды бэкапов.
Главные параметры fio, которые нужно понимать
Большая часть ошибок в тестах возникает из-за непонимания нескольких опций. Разберём базовый набор.
1) --rw — тип нагрузки. Частые значения: read, write, randread, randwrite, rw, randrw. Последовательные тесты используют read/write, случайные — randread/randwrite, смешанные — randrw.
2) --bs — размер блока. Для последовательной пропускной способности часто берут 1M. Для IOPS и баз данных — 4k, 8k, 16k. Чем больше блок, тем выше throughput, но ниже количество операций.
3) --size — размер тестового файла или области. Если указать --size=1G на сервере с 64 ГБ RAM и не использовать direct I/O, тест может оказаться тестом кеша.
4) --direct=1 — обход page cache операционной системы. Для дисковых тестов почти всегда нужен, иначе чтение может идти из памяти. Но учтите: реальные приложения не всегда работают с direct I/O, поэтому такой тест показывает не «скорость приложения», а поведение дисковой подсистемы ближе к низкому уровню.
5) --ioengine — механизм I/O. Для Linux часто используют libaio или io_uring. libaio — проверенный вариант, io_uring актуален на современных ядрах. Если сомневаетесь, начните с libaio.
6) --iodepth — глубина очереди. При iodepth=1 тест показывает одиночные запросы. При iodepth=16, 32, 64 видно, как устройство ведёт себя под параллельной нагрузкой. Для NVMe большая очередь нормальна, для HDD она быстро приводит к росту задержек.
7) --numjobs — количество параллельных worker-процессов или потоков. Это похоже на несколько клиентов, одновременно работающих с диском. Для баз и многопользовательских сервисов тест с numjobs=4 или 8 часто ближе к реальности, чем один поток.
8) --runtime и --time_based — запуск теста по времени. Например, --runtime=60 --time_based. Так удобнее сравнивать результаты между серверами.
9) --ramp_time — прогрев перед измерением. Например, --ramp_time=10 отбросит первые 10 секунд, пока кеши, аллокаторы и контроллер выходят на стабильный режим.
10) --group_reporting — объединяет отчёт по нескольким jobs. Без него вывод может быть слишком подробным.
Базовые команды fio для теста диска
Ниже команды для Linux. В примерах используется файл /mnt/test/fio.test. Замените путь на отдельный тестовый mount point или каталог на нужном диске.
Сначала создайте каталог:
sudo mkdir -p /mnt/test
sudo chown "$USER":"$USER" /mnt/testЕсли каталог уже существует на нужном разделе, менять владельца не обязательно.
1) Подготовка тестового файла
Для случайного чтения лучше заранее создать файл, чтобы тест не измерял аллокацию и первичную запись:
fio --name=prepare \
--filename=/mnt/test/fio.test \
--size=8G \
--rw=write \
--bs=1M \
--direct=1 \
--ioengine=libaio \
--iodepth=16 \
--group_reportingРазмер 8G — пример. На сервере с большим объёмом RAM увеличьте его. Для короткой проверки VPS можно взять меньше, но помните про кеш.
2) Последовательное чтение
fio --name=seqread \
--filename=/mnt/test/fio.test \
--size=8G \
--rw=read \
--bs=1M \
--direct=1 \
--ioengine=libaio \
--iodepth=16 \
--runtime=60 \
--time_based \
--group_reportingЭтот тест показывает, насколько быстро диск отдаёт большие непрерывные данные. Полезно для файловых серверов, резервного копирования, обработки больших логов.
3) Последовательная запись
fio --name=seqwrite \
--filename=/mnt/test/fio.test \
--size=8G \
--rw=write \
--bs=1M \
--direct=1 \
--ioengine=libaio \
--iodepth=16 \
--runtime=60 \
--time_based \
--group_reportingОсторожно: файл будет перезаписан. Не указывайте путь к важному файлу.
4) Случайное чтение 4k
fio --name=randread4k \
--filename=/mnt/test/fio.test \
--size=8G \
--rw=randread \
--bs=4k \
--direct=1 \
--ioengine=libaio \
--iodepth=32 \
--runtime=60 \
--time_based \
--group_reportingЭто один из главных тестов для баз данных и виртуализации. Он показывает IOPS и задержки при мелком случайном чтении.
5) Случайная запись 4k
fio --name=randwrite4k \
--filename=/mnt/test/fio.test \
--size=8G \
--rw=randwrite \
--bs=4k \
--direct=1 \
--ioengine=libaio \
--iodepth=32 \
--runtime=60 \
--time_based \
--group_reportingСлучайная запись обычно тяжелее чтения. На дешёвых VPS, сетевых дисках и SSD без стабильного write cache именно здесь часто видна реальная проблема.
6) Смешанная нагрузка 70/30
fio --name=randrw70read \
--filename=/mnt/test/fio.test \
--size=8G \
--rw=randrw \
--rwmixread=70 \
--bs=4k \
--direct=1 \
--ioengine=libaio \
--iodepth=32 \
--numjobs=4 \
--runtime=60 \
--time_based \
--group_reportingТакой профиль ближе к многим веб-приложениям: чтения больше, но запись тоже есть — сессии, очереди, WAL, логи, обновления строк.
Job-файлы: удобный способ повторять тесты
Однострочные команды хороши для быстрой проверки, но для сравнения серверов лучше хранить профили в job-файлах. Так меньше риск забыть параметр или случайно изменить методику.
Пример fio-randread.fio:
[global]
filename=/mnt/test/fio.test
size=8G
direct=1
ioengine=libaio
runtime=60
time_based=1
ramp_time=10
group_reporting=1
[randread-4k]
rw=randread
bs=4k
iodepth=32
numjobs=4Запуск:
fio fio-randread.fioДля последовательного чтения можно заменить блок:
[seqread-1m]
rw=read
bs=1M
iodepth=16
numjobs=1Если нужно сохранить результат для последующего анализа, используйте JSON:
fio fio-randread.fio --output=fio-result.json --output-format=jsonJSON удобен для автоматизации: можно складывать результаты в артефакты CI, сравнивать несколько серверов, строить графики. Но не превращайте fio в постоянный мониторинг: это нагрузочный тест, а не лёгкий health check.
Как читать результат fio
Вывод fio кажется перегруженным, но для большинства задач достаточно нескольких строк.
Фрагмент может выглядеть так:
read: IOPS=58.2k, BW=227MiB/s (238MB/s)(13.3GiB/60001msec)
slat (usec): min=2, max=810, avg=7.12, stdev=4.90
clat (usec): min=80, max=18234, avg=2180.45, stdev=950.22
lat (usec): min=91, max=18250, avg=2188.10, stdev=952.01
clat percentiles (usec):
| 1.00th=[ 980], 5.00th=[ 1254], 10.00th=[ 1483],
| 50.00th=[ 2057], 90.00th=[ 3359], 95.00th=[ 3916],
| 99.00th=[ 5604], 99.50th=[ 6718], 99.90th=[10421]Смотрите на следующие показатели.
1) IOPS — сколько операций выполняется в секунду. Для 4k random-тестов это главный показатель производительности. Но сравнивать IOPS нужно только при одинаковых bs, iodepth, numjobs, direct и rw.
2) BW — пропускная способность. Для последовательных тестов это основной показатель. Для случайного 4k он вторичен: высокий BW там обычно следует из высокого IOPS.
3) slat — submission latency, время отправки запроса из fio в ядро. Обычно меньше, чем completion latency. Если slat высокий, проблема может быть не только в диске: CPU, системные вызовы, scheduler, перегрузка хоста.
4) clat — completion latency, время до завершения I/O. Это ключевая задержка дисковой операции.
5) lat — полная задержка. Обычно slat + clat.
6) Percentiles — хвосты задержек. Среднее значение может быть нормальным, но 99.00th и 99.90th покажут редкие долгие операции. Для API и баз данных именно они часто превращаются в медленные запросы и таймауты. Подробнее о роли хвостовых задержек — в статье про tail latency и p99.
7) CPU usage — если fio упирается в CPU, тест может не раскрывать диск. Это чаще бывает на очень быстрых NVMe, при маленьком блоке, большом числе jobs или слабом процессоре.
8) Disk utilization — в расширенном выводе и через iostat -x смотрите %util, await, aqu-sz. Если диск на 100% utilization, а задержка растёт, вы нашли насыщение.
Не делайте вывод по одной строке. Проведите несколько тестов с разными iodepth: 1, 4, 16, 32, 64. Так видно, где устройство раскрывается, а где начинает копить очередь. Для понимания влияния планировщика полезен разбор Linux I/O scheduler.
Как получить честный тест диска с помощью fio
Хороший тест должен отвечать на конкретный вопрос. «Какая скорость диска?» — слишком расплывчато. Для сайта на VPS вопрос может звучать так: «Выдержит ли том случайные записи базы без роста p99 выше приемлемого уровня?» Для файлового сервера: «Сколько даёт последовательное чтение большими блоками?» Для очереди: «Как ведёт себя диск при смешанной random-нагрузке 70/30?»
Практическая методика:
1) Зафиксируйте окружение — модель сервера, тип диска, файловая система, mount options, ядро, fio --version, свободное место, объём RAM. Для облака укажите тип тома и лимиты, если провайдер их публикует.
2) Уберите лишнюю нагрузку — остановите тяжёлые batch-задачи, бэкапы, миграции, индексацию. Если это невозможно, хотя бы запишите, что параллельно работало.
3) Используйте файл достаточного размера — он должен быть больше объёма RAM или запускаться с --direct=1, иначе тест измерит page cache, а не диск. Для базового сравнения подойдут 8G, 16G, 32G — ориентируйтесь на RAM и свободное место.
4) Делайте прогрев — --ramp_time=10 и больше для длинных тестов. Короткий тест на 5 секунд часто ловит не диск, а начальное состояние кешей и буферов контроллера.
5) Тестируйте несколько профилей — минимум: последовательное чтение, последовательная запись, случайное чтение 4k, случайная запись 4k, смешанный randrw.
6) Меняйте очередь осознанно — iodepth=1 показывает одиночную задержку, iodepth=32 — поведение под параллелизмом. Не сравнивайте между собой тесты с разным iodepth, если не анализируете масштабирование.
7) Повторяйте тесты — особенно на VPS и сетевых дисках. У облачных провайдеров возможны noisy neighbors, burst-лимиты, фоновые операции. Один прогон может быть случайно хорошим или плохим.
8) Смотрите на latency, а не только на IOPS — если рост IOPS достигается ценой огромного p99, для веб-приложения это может быть хуже, чем меньшая, но стабильная производительность.
После тестов удалите файл:
rm -f /mnt/test/fio.testЕсли тестировали SSD длительными записями, помните про износ и особенности SLC-cache. Дешёвые SSD могут первые минуты писать быстро, а затем резко проседать после заполнения кеша. Для таких случаев короткий runtime=30 почти бесполезен — нужен более длинный прогон.
Частые ошибки при тестировании дисков
1) Сравнивают dd и fio как равные инструменты — dd годится для грубой проверки последовательной записи, но плохо моделирует реальную I/O-нагрузку. fio позволяет задавать random I/O, очередь, потоки, смешанное чтение/запись и latency percentiles.
2) Тестируют кеш вместо диска — маленький файл, отсутствие --direct=1, повторное чтение того же файла. Результат получается красивым, но бесполезным.
3) Запускают запись по рабочему диску в пиковое время — даже тестовый файл способен забить I/O и замедлить базу, Nginx, очереди, логирование. Если пользователи уже жалуются на медленный сайт, синтетическая нагрузка только усугубит проблему.
4) Смотрят только на среднюю задержку — среднее 2 ms не помогает, если p99 регулярно улетает в 100 ms. Для веба и API хвосты часто важнее среднего.
5) Сравнивают разные профили — randread 4k iodepth=32 нельзя сравнивать с read 1M iodepth=1. Это разные нагрузки и разные выводы.
6) Игнорируют файловую систему — тест по файлу включает поведение ext4, XFS, mount options, аллокацию, журналирование. Тест по блочному устройству ближе к железу, но опаснее и не всегда отражает работу приложения.
7) Делают вывод без системных метрик — параллельно с fio полезно смотреть CPU, load average, iowait, память, iostat -x. Если вырос load average, это не всегда CPU-проблема: процессы могут ждать I/O. Подробнее — в статье что такое load average в Linux.
8) Забывают про лимиты хостинга — у VPS и облачных томов могут быть ограничения по IOPS, throughput, burst balance. fio покажет симптом, но причину иногда нужно искать в тарифе или настройках провайдера.
fio, мониторинг и диагностика проблем на сайте
fio отвечает на вопрос «как ведёт себя диск под контролируемой нагрузкой». Он не заменяет мониторинг приложения, базы и доступности сайта.
Если сайт периодически отдаёт 502, 503, медленно открывается или зависает при пиковом трафике, схема диагностики обычно такая:
1) Зафиксировать внешний симптом — когда началась деградация, какие URL затронуты, есть ли ошибки у пользователей. Для этого полезен uptime monitoring: Statuser проверяет сайт с заданным интервалом и присылает уведомление о сбое, а не заставляет ждать жалоб от клиентов.
2) Посмотреть серверные метрики — CPU, RAM, load average, iowait, диск, сеть, база, Nginx. Для постоянного сбора метрик подойдёт связка из Prometheus и Grafana.
3) Проверить текущую I/O-нагрузку — iostat -x 1, iotop, логи базы, slow queries. Если диск уже перегружен, добавлять к нему синтетический тест рискованно.
4) Воспроизвести нагрузку отдельно — на стенде, реплике, новом сервере или в окно обслуживания. Здесь fio помогает понять, хватает ли дисковой подсистемы для вашего профиля.
5) Сопоставить с реальным приложением — если база пишет WAL мелкими синхронными операциями, один тест последовательной записи 1M ничего не докажет. Нужен профиль ближе к реальности: 4k/8k, random, mixed, нужная глубина очереди.
После замены диска, переезда на другой тариф или смены провайдера полезно настроить внешний мониторинг доступности. Если проблема вернётся, Statuser зафиксирует недоступность или рост ошибок снаружи, а серверные метрики помогут связать это с I/O, базой или сетью.
FAQ
Можно ли запускать fio на рабочем сервере?
Можно, но осторожно. Не запускайте тяжёлые write-тесты в пик нагрузки. Используйте отдельный тестовый файл, ограничивайте runtime, следите за iostat, CPU и latency приложения.
Что лучше тестировать: файл или /dev/sdX?
Для большинства хостинг-задач — файл на нужной файловой системе. Тест по /dev/sdX подходит для пустого диска или стенда и может уничтожить данные.
Почему fio показывает больше, чем видит приложение?
Профиль теста может не совпадать с реальной нагрузкой. Например, read 1M показывает высокую последовательную скорость, а приложение делает мелкие синхронные random-записи.
Какие параметры взять для базового теста VPS?
Начните с randread, randwrite, randrw на 4k, direct=1, iodepth=16 или 32, numjobs=1–4, runtime=60. Затем сравнивайте не только IOPS, но и p95/p99 latency.
Похожие статьи

iostat и iotop: диагностика дисковой нагрузки в Linux
Практический разбор команд iostat и iotop: как читать метрики диска, находить процессы и расследовать I/O-проблемы.
26 октября 202610 мин

vmstat и sar: классические инструменты анализа производительности
Практическое руководство по диагностике CPU, памяти, swap, диска и системной нагрузки с помощью vmstat и sar.
27 октября 202610 мин

Команда ping: как пользоваться и правильно читать вывод
Практическое руководство по ping: запуск, параметры, интерпретация вывода и ограничения при диагностике сайтов и серверов.
15 октября 20269 мин
Настроить мониторинг за 30 секунд
Надёжные уведомления о даунтаймах. Без ложных срабатываний