Что такое Linux I/O latency и почему «iowait 30%» ещё ничего не доказывает
Под Linux I/O latency обычно понимают задержку между моментом, когда процесс запросил чтение/запись, и моментом, когда операция реально завершилась. Важно, что в «задержку диска» на практике часто попадает сумма разных компонентов: ожидание page cache, очередь на блочном устройстве, работа планировщика I/O, задержки файловой системы (ext4/xfs), драйверов, контроллера и самого диска или СХД.
Частая ловушка в мониторинге: увидеть высокий iowait и сразу решить «диск умирает». На самом деле iowait — это время, когда CPU простаивает, ожидая завершения I/O, и его величина зависит не только от диска, но и от числа runnable-потоков, поведения приложения и загрузки CPU. На одних системах iowait хорошо коррелирует с проблемами диска, на других — почти нет.
Рабочий подход такой: сначала подтвердить узкое место метриками очереди и латентности на устройстве, затем найти процессы и тип I/O, и только потом лечить (настройкой, ограничениями нагрузки или масштабированием хранилища).
Минимальный чек-лист перед глубоким разбором
Перед тем как включать тяжёлую трассировку, проверьте базовые вещи. В большинстве случаев они быстро показывают направление расследования.
- Есть ли проблема прямо сейчас: «постоянная» деградация или короткие пики.
- Какое устройство страдает: NVMe/SATA, virtio-blk, LVM, mdraid, сетевой блочный том.
- Как проявляется: долгие ответы HTTP, подвисания БД, медленные
fsync, затыки ротаций/логов, рост таймаутов. - Что изменилось: бэкапы, миграции, rebuild индексов, обновление ядра, новые cron-задачи.
Если нужен более широкий разбор инструментов (включая iotop и базовые проверки планировщика), держите под рукой материал про iostat/iotop/fio и I/O scheduler.

iostat: быстро понять, есть ли очередь и где растёт задержка
iostat — инструмент «первого касания»: показывает нагрузку по устройствам, средние задержки и признаки очереди. Он не отвечает на вопрос «кто делает I/O», зато быстро говорит «есть ли проблема на уровне блочного устройства и на каком именно диске/томе».
Установка
Обычно iostat входит в пакет sysstat.
sudo apt-get update
sudo apt-get install -y sysstat
sudo dnf install -y sysstat
Команда, с которой стоит начинать
Смотрите расширенную статистику по устройствам с периодом 1 секунда, 10 итераций:
iostat -x -d 1 10
Ключевые поля (названия могут немного отличаться по версиям):
r/s,w/s— IOPS чтения/записи.rkB/s,wkB/s— пропускная способность.await— среднее время выполнения I/O (включая ожидание в очереди), мс.r_await,w_await— отдельно для чтения/записи (если есть).avgqu-sz— средний размер очереди (сколько запросов в полёте/ожидании).%util— доля времени, когда устройство было занято обработкой запросов.
Поле svctm встречается в некоторых сборках, но считается устаревшим и может вводить в заблуждение, особенно на современных NVMe и виртуализированных дисках.
Как интерпретировать: признаки disk bottleneck
Оценивайте комбинации метрик, а не одну цифру:
- Растут
awaitиavgqu-sz: очередь копится, устройство не успевает «разгрести» запросы. %utilдержится близко к 100%: диск занят постоянно. Для NVMe высокий%utilможет быть нормой при параллельности, но вместе с ростомawaitэто уже тревожный сигнал.- Высокий
awaitпри низком%util: часто намекает на задержки ниже уровня гостевой ОС (например, сеть/СХД, троттлинг, лимиты виртуализации) или на то, что «время ожидания» образуется не на самом устройстве, а выше (ФС/блокировки) и требуется подтверждение другими инструментами.
CPU iowait рядом: полезно, но аккуратно
Параллельно посмотрите сводку по CPU:
iostat -c 1 10
Если %iowait высокий и одновременно в iostat -x на нужном устройстве растут await и avgqu-sz, вероятность дискового узкого места повышается. Если iowait высокий, а на устройствах всё ровно, копайте альтернативы: блокировки в приложении, сеть, swap, cgroup-лимиты, ожидание внешних систем.
pidstat: найти виновника по процессам и типам I/O
pidstat помогает ответить на вопрос «кто именно давит на I/O» и часто сокращает расследование в разы: вместо абстрактного «диск занят» вы видите конкретный PID и команду.
Базовый просмотр I/O по процессам
pidstat -d 1 10
Обратите внимание на:
kB_rd/s,kB_wr/s— скорость чтения/записи.kB_ccwr/s— cancelled write: запись, которая была отложена и затем отменена (часто связано с буферизацией в page cache).
Если в момент деградации один процесс стабильно лидирует по записи или чтению — вы уже близко к причине (бэкап, ротация, rebuild индекса, compaction, rsync, архиватор и т.д.).
Сопоставление с iostat
Надёжная связка выглядит так:
- iostat показывает рост
await/avgqu-szна конкретном устройстве (например,vdaилиnvme0n1). - pidstat -d показывает процессы, которые в тот же момент создают основную нагрузку по I/O.
Если процессы «пишут много», а на устройстве задержка растёт — это классический bottleneck диска/тома/ФС. Если процессы «пишут мало», но задержка огромная — проверьте синхронные операции (fsync), мелкие IOPS, особенности журналирования ФС или проблемы на нижнем слое хранения.
Кейс «много операций, но throughput маленький»
Ситуация, когда w/s высокое, а wkB/s низкое, часто означает мелкие записи. Это типично для БД, очередей, логирующих сервисов и сценариев с частыми flush/fsync. В таком профиле средняя латентность и особенно хвосты могут расти даже при «скромной» пропускной способности.
blktrace: увидеть, где именно в стеке возникает задержка
Когда iostat подтвердил рост задержек на устройстве, а pidstat показал подозрительные процессы (или не показал ничего очевидного), приходит время blktrace. Он трассирует события блочного слоя и помогает понять: запросы долго лежат в очереди или их долго обслуживает устройство.
Важно: blktrace может быть шумным
Запускайте blktrace точечно: на конкретном устройстве и на короткий интервал. На продакшене заранее оцените риск и выбирайте окно низкой нагрузки.
Установка
sudo apt-get update
sudo apt-get install -y blktrace
sudo dnf install -y blktrace
Быстрый запуск на устройстве
Например, для /dev/vda:
sudo blktrace -d /dev/vda -o -
Сырой поток событий читать тяжело, поэтому чаще используют blkparse и сводные утилиты из набора blktrace.
Сводка через btt: очередь vs сервис устройства
Практичный сценарий — собрать трассу 10–30 секунд и прогнать анализ:
sudo blktrace -d /dev/vda -w 15 -o /tmp/vda
sudo blkparse -i /tmp/vda -o /tmp/vda.parsed
sudo btt -i /tmp/vda
В отчёте btt полезны распределения задержек и вклад стадий. В упрощении:
- Долго до отправки на устройство: задержка в очереди/планировании/конкуренции (слишком много параллельных запросов, ограничения слоя хранения, неудачный scheduler, влияние виртуализации).
- Долго обслуживается устройством: само хранилище не успевает (перегруз, GC на SSD, троттлинг, деградация массива, кэш контроллера и т.п.).
Практическая цель blktrace
Цель не в том, чтобы «прочитать все события», а в том, чтобы получить доказательство, где живёт latency. Дальше проще выбирать лечение: ограничить фоновые задачи, сменить шаблон доступа, исправить параметры ФС или масштабировать/менять хранилище.
fio: подтвердить пределы диска и воспроизвести симптомы
После того как вы увидели признаки disk bottleneck, полезно понять «какой предел у этого тома в принципе» и как он ведёт себя на разных профилях. Для этого используют fio.
Установка fio
sudo apt-get update
sudo apt-get install -y fio
sudo dnf install -y fio
Важное правило безопасности
fio легко просаживает продакшен. Тестируйте на отдельном тестовом томе/файле или в окно обслуживания. Тяжёлые random-write профили по боевому хранилищу БД запускайте только осознанно.
Пример: измерить латентность случайного чтения 4K
Тест в файл (в каталоге с нужной ФС) часто безопаснее, чем по raw-устройству:
fio --name=randread4k --filename=/var/tmp/fio.test --size=2G --direct=1 --rw=randread --bs=4k --iodepth=32 --numjobs=1 --time_based=1 --runtime=30 --group_reporting
Смотрите прежде всего на хвосты:
- lat и percentiles: 95/99 перцентили часто важнее среднего.
- IOPS и стабильность результата между прогонами.
Пример: случайная запись 4K (осторожно)
fio --name=randwrite4k --filename=/var/tmp/fio.test --size=2G --direct=1 --rw=randwrite --bs=4k --iodepth=32 --numjobs=1 --time_based=1 --runtime=30 --group_reporting
Если fio показывает высокую latency уже на умеренной глубине очереди, а iostat на продакшене демонстрирует похожие значения await, это сильный аргумент, что проблема действительно в подсистеме хранения, а не в «мистике приложения».

Где здесь ext4 и xfs: как ФС влияет на задержки
Важно: ext4 и xfs по-разному ведут себя на метаданных, параллельной записи и разных паттернах доступа. Нет универсального «xfs всегда быстрее» или «ext4 всегда надёжнее» — решает профиль нагрузки и настройка системы.
Типовые случаи, когда latency растёт из-за ФС
- Много мелких файлов и частые fsync: метаданные и журнал становятся узким местом.
- Параллельная запись многими процессами: при неудачном сочетании параметров монтирования и профиля нагрузки растёт очередь.
- Фоновая активность: reclaim, writeback, периодические flush, TRIM/discard (в зависимости от реализации и слоя хранения).
Практика простая: сначала измеряйте (iostat/pidstat/blktrace), потом меняйте. Случайные «тюнинги» без замеров часто ухудшают хвостовые задержки.
Пошаговый сценарий расследования I/O latency на продакшене
- Зафиксируйте момент деградации: время, что именно «тормозит», какие сервисы затронуты.
- Проверьте устройства:
iostat -x -d 1 10, найдите том с ростомawait/avgqu-sz. - Найдите процессы:
pidstat -d 1 10, сопоставьте с окном деградации. - Подтвердите природу задержки: краткий
blktraceи анализ черезbtt(очередь vs сервис). - Сформулируйте гипотезу: мелкие синхронные записи, фоновые джобы, неверный параллелизм, упор в лимиты слоя хранения, конкуренция на одном томе.
- Проверьте fio (по возможности в тестовой среде), чтобы оценить потолок и хвостовые задержки.
- Лечите точечно: ограничьте фон, разнесите write-heavy задачи, измените batching/flush в приложении, разделите БД и логи, масштабируйте диск/том.
Частые причины высокой латентности и что делать в первую очередь
Ниже — типовые кейсы, которые чаще всего дают всплески latency и iowait, и куда смотреть без гаданий.
- Бэкапы/архивация/сжатие логов: проверьте
pidstat, ограничьте I/O планированием работ и расписанием. - База данных и fsync: обычно упирается в tail latency на записи. Ищите пики мелких операций и конкуренцию за один том.
- Почти нет свободного места: ФС начинает вести себя хуже, растёт стоимость аллокаций и фрагментация.
- Виртуализация и «шумные соседи»: на госте вы видите рост
await, но причина вне ОС. blktrace/btt часто помогает показать, что задержка в очереди/слое хранения. - Смешанный профиль на одном томе: БД, логи, временные файлы и кэши вместе дают конкуренцию и предсказуемые пики.
Если деградация проявляется на уровне приложений, не забывайте про сторону сервиса: иногда «диск» оказывается лишь следствием. Например, при PHP-нагрузке полезно уметь быстро включать slowlog и отличать ожидание I/O от блокировок в коде: гайд по PHP-FPM slowlog.
Итоги: как связать iostat, pidstat и blktrace в одну картину
iostat отвечает «есть ли рост задержки/очереди и на каком устройстве». pidstat — «какие процессы генерируют I/O прямо сейчас». blktrace — «где именно рождается задержка в блочном стеке: очередь или сервис устройства». А fio помогает подтвердить пределы подсистемы хранения и воспроизвести проблему на контролируемом профиле.
Лучший результат даёт не разовая героическая диагностика, а повторяемый runbook: короткие замеры iostat/pidstat в момент деградации, точечный blktrace при необходимости и аккуратный fio на тестовом окружении. Так вы быстрее переходите от «сервер тормозит» к конкретному плану действий.


