Бенчмаркинг дисковой подсистемы: где теряется производительность
Дисковая подсистема почти всегда оказывается тем самым звеном, которое первым упирается в потолок, когда нагрузка вырастает. База данных начинает отдавать запросы дольше, очередь накапливает необработанные сообщения, виртуальные машины на общем хранилище «подвисают» — и всё это при том, что процессор и память загружены наполовину. Бенчмаркинг дисковой подсистемы нужен не ради красивых цифр в отчёте, а чтобы отделить реальное узкое место ввода-вывода от симптомов, которые на него лишь похожи.
Проблема в том, что без измерений причину ищут наугад. Администратор видит рост задержек операций чтения и записи, добавляет памяти, меняет параметры ядра, переносит сервис на другой узел — а деградация возвращается через неделю, потому что корень был в другом: в исчерпании очереди на накопителе, в неверном размере блока, в том, что профиль нагрузки на запись не совпадает с профилем, под который подбирали хранилище. Каждая такая итерация — это простой, потерянное время команды и риск для сервиса, который всё это время работает на пределе.
Производительность дисковой подсистемы нельзя оценить одним числом. Последовательное чтение большими блоками, случайная запись мелкими, смешанная нагрузка с преобладанием чтения — это три разных сценария с разным поведением, и оптимизация под один легко ухудшает два других. Поэтому корректный замер всегда начинается с вопроса «какой профиль у нашей реальной нагрузки», а не с запуска первого попавшегося теста.
Дальше разбираем, как это закрывается: какие сценарии воспроизводим, как снимаем метрики задержек и пропускной способности, и как по результатам отличить нехватку ресурса хранилища от ошибки в конфигурации приложения.
Что даёт корректный замер: режимы нагрузки и метрики
Корректный замер начинается с выбора профиля нагрузки, а не с запуска первой попавшейся команды. Последовательное чтение блоками по несколько мегабайт показывает потолок пропускной способности — это сценарий резервного копирования и выгрузки больших файлов. Случайный доступ блоками по 4 КБ с глубиной очереди 32 воспроизводит работу базы данных: здесь потолок задаёт не пропускная способность, а задержка на операцию.
Профили нагрузки: что и зачем мерить
- Последовательный доступ — крупные блоки, один поток или несколько. Показывает, сколько данных пройдёт при копировании, стриминге, репликации.
- Случайный доступ — мелкие блоки, высокая глубина очереди. Показывает поведение под транзакционной нагрузкой и при смешанном чтении-записи.
- Смешанный режим — доля записи 70/30 или 50/50. Ближе всего к реальной работе сервиса, где чтение и запись идут одновременно.
Метрики, по которым принимают решение
Пропускная способность (МБ/с) отвечает на вопрос «успеет ли перенести данные за окно обслуживания». Задержка — на 95-м и 99-м процентиле — отвечает на вопрос «не начнут ли запросы к базе упираться в диск». Средняя задержка врёт: редкие, но долгие операции тонут в общем числе и не видны, а именно они дают всплески отклика приложения. Поэтому смотрим на хвост распределения, а не на среднее.
Чем мерить: сравнение подходов
| Инструмент | Когда подходит | Ограничения |
|---|---|---|
| fio | Гибкие профили: задаётся размер блока, глубина очереди, доля записи, число потоков. Основной инструмент для воспроизводимых замеров | Требует аккуратной конфигурации — неверные параметры дают красивый, но бессмысленный результат |
| bonnie++ | Быстрая проверка файловой системы и дискового ввода-вывода «из коробки» | Меньше контроля над профилем, хуже подходит для точного сравнения конфигураций |
| dd | Разовый замер последовательной записи и чтения, проверка «диск вообще живой» | Не даёт задержек и случайного доступа, легко обманывается кэшем |
Для воспроизводимости наши инженеры прогревают кэш, фиксируют размер файла больше объёма памяти, отключают кэширование на уровне файловой системы и прогоняют каждый профиль несколько раз. Иначе разброс между запусками перекрывает разницу между конфигурациями, и замер теряет смысл. Сравнение ведём на одном и том же наборе параметров — так видно эффект от смены типа диска, настроек массива или файловой системы, а не шум. Результаты сводим в таблицу «профиль — пропускная способность — задержка p95/p99», по ней и принимается решение о конфигурации.
fio
Как мы проводим измерение: этапы инженерной работы
Прежде чем запускать замеры, мы разбираем задачу: какой профиль нагрузки важен — случайное чтение мелкими блоками, последовательная запись крупными, смешанный поток с преобладанием чтения. От этого зависит выбор инструмента и параметров, иначе цифры получаются красивыми, но к реальной работе не относятся. Дальше фиксируем целевую конфигурацию — тип носителя, режим кэширования, файловую систему, — чтобы стенд повторял продуктив, а не абстрактное «железо вообще».
- Аудит задачи и постановка гипотезы. Собираем требования приложения: размер блока ввода-вывода, доля чтения и записи, глубина очереди, чувствительность к задержке. Формулируем, что именно проверяем — потолок пропускной способности, поведение под нагрузкой или деградацию со временем.
- Подготовка стенда для замеров. Разворачиваем чистую конфигурацию, отключаем фоновые процессы и лишний кэш, выравниваем разделы, прогреваем носитель перед серией. Один и тот же сценарий прогоняем на разных настройках, меняя только одну переменную за раз.
- Снятие профиля нагрузки. Прогоняем серию замеров на нескольких инструментах, чтобы исключить ошибку методики: один даёт детальную картину по задержкам, второй — устойчивый поток, третий — быструю проверку на последовательных операциях. Расхождение между ними — сигнал перепроверить условия.
- Разбор результатов и поиск узкого места. Смотрим не средние, а распределение задержек: девяносто девятый процентиль показывает, что почувствует пользователь, тогда как среднее его скрывает. Сопоставляем замеры с настройками файловой системы, планировщика и кэша.
- Проверка рекомендаций повторным прогоном. Каждую настройку подтверждаем контрольным замером на том же сценарии — иначе это догадка, а не вывод. Фиксируем, какой параметр дал прирост, а какой оказался нейтральным.
- Передача отчёта с замерами. Отдаём таблицы по каждому сценарию, графики распределения задержек, список изменённых параметров и ожидаемый эффект. Отдельно отмечаем, какие выводы переносятся на продуктив, а какие привязаны к стенду.
- Рекомендации по настройке. Сводим результат в конкретные правки конфигурации и порядок их применения, чтобы команда могла внедрить их без повторного разбора.
Такой порядок убирает главную проблему замеров — когда цифры есть, а решения на их основе принять нельзя. Опишите вашу задачу и текущую конфигурацию — вернёмся с оценкой и планом работ.
Чем синтетический тест отличается от реальной нагрузки?
Синтетический тест подаёт на диск заранее заданный поток операций: фиксированный размер блока, глубину очереди, долю чтения и записи, отсутствие конкуренции за ресурс. Реальная нагрузка так не выглядит — она неоднородна по времени, зависит от кэша файловой системы, от того, как приложение группирует запросы, и от того, что происходит на соседних слоях: сеть, база, планировщик. Поэтому цифры из отчёта утилиты и поведение боевой системы расходятся не потому, что инструмент врёт, а потому что измеряют разное.
Ключевой источник расхождения — кэш. Если тест читает файл, который уже лежит в страничном кэше, замер показывает скорость памяти, а не носителя. Корректный замер требует либо прямого ввода-вывода в обход кэша, либо предварительного сброса кэша перед каждым прогоном, иначе достоверность замеров падает до нуля. Второй фактор — очереди: глубина очереди в тесте задаётся вручную, а в бою её формирует число одновременных запросов от приложений. Один и тот же носитель на глубине очереди 1 и на глубине 32 ведёт себя как два разных устройства.
Третий слой — условия корректного сравнения. Сравнивать два варианта хранения можно, только если совпадают размер блока, доля чтения и записи, глубина очереди, способ обхода кэша и длительность прогона. Смена любого параметра между замерами делает вывод недействительным. Отдельно стоит помнить про прогрев: первые секунды теста носитель и контроллер ещё выходят на режим, поэтому короткие прогоны показывают завышенный или заниженный результат.
Практический вывод: синтетический тест отвечает на вопрос «какова верхняя граница этого носителя при заданном профиле», а не «как система поведёт себя под нагрузкой». Он нужен, чтобы отсеять заведомо неподходящие варианты и поймать деградацию после изменений, но решение о конфигурации принимается по смешанному сценарию, приближенному к профилю приложения. Мы строим такие сценарии по логам реальных операций и держим одинаковые условия между прогонами — тогда сравнение даёт ответ, который подтверждается на боевой системе.
Кейс: как замеры убрали деградацию хранилища
Кластер виртуализации из шести узлов обслуживал продуктовый контур: базы, кеш, очереди. Жалобы шли волнами — «вечером всё тормозит», но метрики процессора и памяти оставались в норме, поэтому проблему списывали на приложение. Пока не сняли профиль ввода-вывода на уровне томов: выяснилось, что пиковые операции чтения упираются в очередь дискового массива, а задержка накопителя растёт ступенями при достижении определённого уровня одновременных запросов.
Что показали замеры
Сначала сняли базовую линию: последовательные и случайные операции чтения и записи при разном размере блока, разном числе одновременных потоков и глубине очереди. Прогоны делали на пустом томе и на боевом, чтобы увидеть разницу между «паспортной» скоростью и реальной картиной под нагрузкой. Отдельно проверили профиль смешанной нагрузки — доля чтения к записи соответствовала продакшену.
Картина оказалась нелинейной: до определённого числа одновременных операций задержка держалась ровно, дальше росла в разы. Это и был источник вечерних провалов — приложение увеличивало параллелизм, а накопитель отвечал очередью вместо данных.
Что изменили
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Настройка планировщика и глубины очереди | Латентность растёт при параллелизме | Не помогает, если упирается в физику носителя |
| Разделение томов по профилю нагрузки | Смешанные чтение и запись на одном массиве | Требует пересборки томов и миграции данных |
| Кеш записи на уровне контроллера | Преобладает запись | Риск потери данных без защищённого питания |
| Замена носителей на быстрые | Исчерпан ресурс и запас по латентности | Капитальные затраты, простой на миграцию |
Выбрали комбинацию: развели тома по профилю, настроили планировщик под смешанную нагрузку и ограничили параллелизм на стороне приложения. Замеры повторяли после каждого шага — чтобы видеть вклад именно этого изменения, а не суммарный эффект.
Результат
Задержка накопителя под пиковой нагрузкой выровнялась, разброс между минимальным и максимальным временем отклика сократился в разы. Вечерние провалы пропали как класс: узкое место перестало быть скрытым. Побочный эффект — приложение перестало «догонять» очередь повторами, нагрузка на кластер снизилась.
Методологию замеров зафиксировали в регламенте: те же прогоны теперь идут перед каждым расширением хранилища, и деградация ловится на этапе планирования, а не в проде. Инструментарий — fio для профилей ввода-вывода и bonnie++ для файловых операций; связка закрывает и синтетику, и поведение под реальной нагрузкой.
Сомнения перед стартом: совместимость, доступы, откат
Бенчмаркинг дисковой подсистемы на боевом сервере — законный вопрос: замеры создают нагрузку, а часть утилит пишет тестовые файлы прямо в рабочую файловую систему. Мы не запускаем замеры «в лоб» на продуктивном контуре. Сначала снимаем профиль текущей нагрузки, выбираем окно минимальной активности и подбираем режим, при котором тест не конкурирует с рабочими процессами за дисковую очередь.
Что если замеры всё-таки заденут боевую систему?
Перед запуском фиксируем точку возврата: снимок конфигурации, текущие параметры монтирования и планировщика ввода-вывода, список запущенных сервисов. Тестовые файлы пишем в отдельный каталог с ограничением по размеру и времени, а не поверх рабочих данных. Если нагрузка выходит за согласованный порог — замер останавливается, изменения откатываются по заранее описанному плану, сервис возвращается к исходному состоянию.
Что если нужен доступ к продакшену? Работаем по принципу минимально необходимых прав: чтение метрик и конфигурации, запуск утилит в согласованном окне, без постоянного доступа администратора. Все действия логируются, доступ выдаётся на время работ и закрывается по завершении.
Что если замеры покажут деградацию? Это и есть результат: отчёт с профилем нагрузки, узкими местами и рекомендациями по настройке — без изменений в конфигурации до вашего согласования.
По итогам работ вы получаете на руки:
- скрипты запуска замеров с зафиксированными параметрами и понятными порогами;
- профиль текущей нагрузки и результаты замеров в читаемом виде;
- план отката изменений с точками возврата;
- перечень выданных доступов и прав с порядком их закрытия;
- документацию по методике замеров, чтобы повторить их самостоятельно;
- рекомендации по настройке дисковой подсистемы с обоснованием каждого изменения.
Опишите задачу и текущий контур — вернёмся с оценкой и планом работ, включая схему безопасного проведения замеров.







