Диагностика диска: iostat и чтение await, %util

Рейтинг: 66.7% · 13 голосов
Подробный курс по диагностике и производительности Linux для админов и DevOps: с чего начать, методология USE, логи (journalctl, dmesg), процессы, CPU, память и OOM, диск и IO (iostat), сеть (ss, tcpdump), системные вызовы и strace, ltrace, perf, флеймграфы, ftrace, eBPF и bpftrace, lsof, мониторинг. Разбор каждого инструмента с чтением вывода.
Ответить
Аватара пользователя
Dmitry_SRE
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Диагностика диска: iostat и чтение await, %util

Сообщение Dmitry_SRE »

Оглавление курса (47)
  1. С чего начать диагностику Linux: методология вместо паники
  2. Первые 60 секунд: экспресс-диагностика нагруженного сервера
  3. Методологии диагностики: USE, RED и здравый смысл
  4. Логи systemd через journalctl: где искать причину
  5. Где лежат логи Linux: /var/log, dmesg и rsyslog
  6. Источники правды: load average, /proc и /sys
  7. Процессы Linux: ps, pstree и состояния процессов
  8. Интерактивный мониторинг: top и htop
  9. Метрики процессов во времени: pidstat
  10. Приоритеты и ограничения: nice, ionice, cgroups
  11. Сигналы и зависшие процессы: kill, и что делать с D-state
  12. Загрузка CPU: user, system, iowait, steal и контекст-свитчи
  13. Диагностика CPU по ядрам: vmstat и mpstat
  14. Профилирование CPU: perf top и поиск пожирателя
  15. Частоты, троттлинг и NUMA: turbostat и numastat
  16. Память Linux: RSS, VSZ, page cache и миф о нехватке памяти
  17. Сколько памяти занято: free, /proc/meminfo и vmstat
  18. Поиск утечек и пожирателей памяти: smem, pmap, smaps
  19. Swap и подкачка: swapon, swappiness, когда своп - это боль
  20. OOM killer: кто и за что убил процесс
  21. Память ядра и slab: slabtop и куда уходит RAM
  22. Подсистема ввода-вывода: путь запроса от приложения до диска
  23. Диагностика диска: iostat и чтение await, %util (вы здесь)
  24. Кто грузит диск: iotop и атрибуция io процессам
  25. Файловые системы: df, du, иноды и куда делось место
  26. Глубокая диагностика блочного слоя: blktrace и biolatency
  27. Кеш страниц и грязные данные: dirty pages, fsync, drop_caches
  28. Сетевой стек Linux: путь пакета и где возникают задержки
  29. Сокеты и соединения: ss и netstat
  30. Захват трафика: tcpdump для диагностики сети
  31. Задержки и потери в сети: ping, mtr, диагностика латентности
  32. Сеть как источник проблем: nftables, conntrack, дропы
  33. Что такое системный вызов и зачем его трассировать
  34. strace: трассировка системных вызовов на практике
  35. strace в бою: почему программа висит, падает или тормозит
  36. ltrace: трассировка вызовов библиотек
  37. Накладные расходы трассировки и безопасные альтернативы
  38. perf: универсальный профайлер Linux
  39. Флеймграфы: визуализация профиля производительности
  40. Трассировка ядра: ftrace и trace-cmd
  41. eBPF: революция в наблюдаемости Linux
  42. Инструменты eBPF на практике: BCC и bpftrace
  43. lsof: открытые файлы, дескрипторы, кто держит файл и порт
  44. Разбор кейса: приложение тормозит - пошаговая диагностика
  45. Непрерывный мониторинг: sar, node_exporter, Grafana, Zabbix
  46. Диагностика в контейнерах: cgroups, лимиты, Docker и Kubernetes
  47. Карта инструментов и сквозной разбор инцидента производительности
Знакомая картина: приложение тормозит, база отвечает с задержками, бэкап ползёт целую вечность. Ты смотришь в top, а там процессор почти простаивает. CPU свободен, памяти навалом, а всё равно медленно. В девяти случаях из десяти виноват диск - он просто не успевает отдавать данные. И вот тут начинается диагностика диска в Linux по-взрослому, без гадания на кофейной гуще.

Главная боль новичка в том, что "диск тормозит" - это ощущение, а не цифра. Чтобы из ощущения получить факт, нужен инструмент, который покажет: сколько операций в секунду диск тянет, сколько данных гоняет и - самое важное - сколько миллисекунд каждый запрос ждёт ответа. Этот инструмент - iostat. В этом уроке разберём его по косточкам: что такое iostat util, что значит await, как по двум-трём колонкам понять, узкое место у тебя диск или нет, и куда копать дальше, когда iostat уже сказал своё слово.

Откуда брать iostat и как его запускать

iostat не входит в базовую поставку большинства систем, он живёт в пакете sysstat. Ставим:

Код: Выделить всё

# Ubuntu / Debian / Astra Linux
sudo apt install sysstat

# RHEL / Fedora / RED OS / ALT
sudo dnf install sysstat
Версии sysstat на 2026 - это ветка 12.x (в свежих дистрибутивах 12.6-12.7). Это важно: именно в 12.0 выпилили колонку svctm (среднее время обслуживания), потому что на современных multi-queue блочных устройствах её честно посчитать нельзя. Если в чьём-то старом мануале ты видишь совет "смотри svctm" - это устаревший совет, забудь про эту колонку. Также в 12.x появились колонки rareq-sz/wareq-sz (средний размер запроса) и блок discard-метрик (d/s, dkB/s, d_await) для TRIM на SSD. Об этом ниже.

Запускать iostat без аргументов почти бесполезно: он покажет средние значения с момента загрузки системы. Это как спросить "какая была средняя скорость машины за всю её жизнь" - цифра есть, толку ноль. Нам нужна картина прямо сейчас, в динамике. Поэтому рабочая команда такая:

Код: Выделить всё

iostat -xz 1
Разберём флаги. -x - расширенный вывод, именно он даёт нам await, %util, очередь и размеры запросов. Без него ты увидишь только огрызок (tps и kB/s). -z - не показывать устройства, у которых за интервал не было активности (чтобы не засорять экран нулями). 1 - обновлять раз в секунду. Первый блок вывода всё ещё усреднён с момента загрузки - его пропускай, смотри на второй и последующие, они отражают живую нагрузку на диск. Полезные добавки: -h делает вывод человекочитаемым (выравнивает колонки, переводит в МБ/ГБ), а -p sda или -p nvme0n1 фокусирует вывод на конкретном устройстве. Для постоянного мониторинга на 2026 чаще берут node_exporter + Prometheus + Grafana (метрики node_disk_io_time_seconds_total и node_disk_*_seconds_total - это те же данные из /proc/diskstats, что читает и iostat), но для ручного разбора инцидента iostat остаётся инструментом номер один.

Изображение

Чтение вывода iostat по колонкам - самое главное

Вот типичный кусок вывода для устройства sda (HDD под нагрузкой). Не пугайся, сейчас пройдёмся по каждой цифре. Реальный вывод sysstat 12.x шире, я оставил ключевые колонки:

Код: Выделить всё

Device  r/s   w/s   rkB/s    wkB/s rareq-sz wareq-sz aqu-sz r_await w_await  %util
sda    12.0 340.0   480.0  46000.0    40.0    135.3  18.50    8.30   72.40  99.20
Идём слева направо.
  • r/s и w/s - это IOPS, число операций чтения и записи в секунду (уже после слияния смежных запросов ядром). Здесь 12 чтений и 340 записей. Это интенсивность, "сколько раз в секунду диск дёргают".
  • rkB/s и wkB/s - пропускная способность, сколько килобайт в секунду читается и пишется. 46 МБ/с записи - для одиночного HDD это уже близко к потолку при не-последовательной записи.
  • rareq-sz и wareq-sz - средний размер одного запроса в килобайтах. Тут запись по 135 КБ - это крупные запросы, похоже на потоковую/последовательную нагрузку. Маленькие значения (4-16 КБ) - признак случайного мелкоблочного ввода-вывода (типичная база данных). По этой колонке ты сразу понимаешь характер нагрузки.
  • r_await и w_await - вот оно, сердце диагностики. Это среднее время в миллисекундах от момента, как запрос попал в очередь, до момента, как диск его выполнил и вернул ответ. То есть полное время ожидания глазами приложения, включая стояние в очереди. w_await тут 72 мс - это очень много. Приложение, которое пишет на этот диск, на каждую запись ждёт по 72 мс. В старых версиях была одна общая колонка await - она и сейчас есть в неразбитом выводе, но r_await/w_await информативнее, потому что чтение и запись могут вести себя совершенно по-разному.
  • aqu-sz (в старых версиях называлась avgqu-sz) - средняя длина очереди: число запросов в очереди планировщика плюс уже отданные устройству, но ещё не завершённые. Грубо - сколько запросов в среднем "висит в работе" одновременно. 18.5 - очередь забита, диск захлёбывается. Эту цифру удобно сопоставлять с типом устройства: для одного HDD aqu-sz больше 1-2 уже означает, что запросы стоят и ждут.
  • %util - доля времени интервала, в течение которого к устройству был отдан хотя бы один запрос. 99.2% значит, что устройство почти всё время было чем-то занято. Запомни формулировку "хотя бы один запрос" - дальше она нас спасёт от грубой ошибки.
Если в выводе мелькают ещё колонки: d/s, dkB/s, d_await - это discard/TRIM-запросы (актуально для SSD/NVMe, чистка освобождённых блоков). f/s, f_await - flush-запросы (сброс кэша на устройство, важно для журналируемых ФС и баз с fsync). Высокий f_await при низком общем потоке - частый симптом проблем с fsync-нагрузкой у баз данных, держи это в уме.

Теперь про нормы, потому что без них цифры мёртвые. Ориентир по await (актуально на 2026):
  • HDD (обычный жёсткий диск): норма await - единицы и десятки миллисекунд. 5-15 мс при умеренной нагрузке - ок. Сотни мс - диск перегружен, очередь стоит колом.
  • SATA SSD: норма - доли миллисекунды и единицы мс. Если SATA SSD стабильно даёт await 10+ мс, что-то не так: либо он деградирует/умирает, либо нагрузка дикая, либо упёрлись в шину SATA.
  • NVMe: здесь счёт идёт на десятки и сотни микросекунд, то есть await обычно заметно меньше 1 мс. Стабильно несколько миллисекунд - уже повод присмотреться (проверь тепловой троттлинг, заполненность, версию прошивки).
Главная ловушка: почему iostat util врёт на SSD и NVMe

Самое распространённое заблуждение, на котором горят даже опытные админы: "%util равен 100, значит диск - узкое место". Для старого HDD это было правдой: блин один, головка одна, он физически делает одну операцию за раз. 100% занятости = упёрлись в потолок.

Но SSD и особенно NVMe умеют обрабатывать много запросов параллельно - десятки и сотни одновременно (у NVMe сотни аппаратных очередей по тысячам команд). А %util по своей механике считает просто "был ли в устройстве хотя бы один запрос в этот момент времени". Он не знает, сколько ещё запросов диск мог бы взять сверху. Поэтому NVMe легко показывает %util 100%, а на деле используется процентов на десять от реальной мощности. Это не баг iostat, а фундаментальное ограничение метрики на multi-queue устройствах - о нём давно предупреждают и Brendan Gregg, и Marc Brooker. Для таких дисков %util - индикатор "диск не спит", но НЕ индикатор насыщения. Та же ловушка касается RAID-массивов и device-mapper (LVM, mpath): там %util агрегированного устройства тоже почти бессмыслен.

Куда смотреть вместо %util на SSD/NVMe? На связку await, w_await/r_await и aqu-sz. Если очередь (aqu-sz) растёт, а await вместе с ней ползёт вверх - вот это настоящее насыщение: запросы копятся быстрее, чем диск успевает их разгребать. Если же aqu-sz маленькая (меньше 1-2) и await низкий, то %util 100% можно смело игнорировать - диску ещё далеко до предела. Практический приём: гони на устройство всё больше нагрузки и следи, на каком aqu-sz await начинает резко расти - вот эта точка перегиба и есть реальный потолок твоего диска по latency.

Связь iowait и await - не путай их

Новички часто видят в top или vmstat показатель iowait (он же %wa или wa) и думают, что это и есть "загрузка диска". Это не так. iowait linux - это доля времени, когда процессор простаивал, потому что ждал завершения операций ввода-вывода и при этом ему было больше нечего делать. Это метрика CPU, а не диска.

Высокий iowait - сигнал "процессор часто скучает в ожидании диска". Но он коварен: на машине с быстрым многоядерным CPU iowait может быть низким даже при адском диске, потому что свободным ядрам есть чем заняться - iowait усредняется по всем ядрам. И наоборот, на однопоточной задаче iowait взлетит до небес. Поэтому iowait - это намёк "копай в сторону диска", а конкретику про нагрузку на диск в Linux даёт именно iostat и его await. На 2026 есть более честный сигнал давления ввода-вывода - PSI (Pressure Stall Information), он считает реальное "залипание" задач из-за I/O независимо от числа ядер:

Код: Выделить всё

cat /proc/pressure/io
# some avg10=23.5 avg60=18.2 avg300=9.8 total=...
Поле some avg10 - доля времени за последние 10 секунд, когда хотя бы одна задача тормозила из-за I/O. Если оно стабильно высокое - системе реально плохо от диска, и это надёжнее, чем iowait. Алгоритм простой: увидел высокий iowait в top или давление в /proc/pressure/io - сразу беги в iostat -xz 1 и смотри await с aqu-sz по конкретным устройствам.

Когда iostat не хватает: переходим на eBPF (актуально на 2026)

iostat даёт усреднённые по секунде цифры. Но средний await 2 мс может скрывать редкие выбросы в 200 мс, которые и портят жизнь приложению (хвост распределения, p99). Здесь iostat слеп. На 2026 стандарт де-факто для глубокого разбора латентности диска - инструменты на eBPF из пакетов bcc (bpfcc-tools) и bpftrace. Они почти бесплатны по накладным расходам, потому что считают гистограммы прямо в ядре.

Код: Выделить всё

# гистограмма задержек блочного I/O (по Ctrl-C)
sudo biolatency-bpfcc

# то же одной строкой через bpftrace
sudo biolatency.bt

# кто именно генерит I/O: процесс, операция, размер, latency
sudo biosnoop-bpfcc
biolatency показывает распределение задержек гистограммой - сразу видно, есть ли длинный хвост. biosnoop выводит каждую операцию с PID, именем процесса и её latency - так ловят "кто конкретно дёргает диск". Это не замена iostat, а следующий шаг: iostat говорит "диску плохо", а biolatency/biosnoop отвечают "плохо вот настолько и из-за вот этого процесса". Требования: ядро 4.x+ (на 2026 у всех 5.x-6.x), пакеты bpfcc-tools или bpftrace, права root. На Astra Linux и RED OS эти пакеты тоже есть в репозиториях.

Типичные грабли и заблуждения
  • Смотрят на первый блок вывода iostat. Он усреднён с загрузки и к текущей ситуации отношения не имеет. Всегда читай со второго блока.
  • Меряют диск по %util на NVMe/SSD/RAID. Разобрали выше - на параллельных устройствах это пустышка для оценки насыщения. Смотри await + aqu-sz.
  • Ищут колонку svctm. Её нет с sysstat 12.0, она удалена как недостоверная на multi-queue. Совет из старых статей устарел.
  • Путают пропускную способность и IOPS. Бэкап одним большим потоком даёт огромные kB/s при низком r/s и большом wareq-sz - это норма. База с мелкими случайными запросами даёт высокий r/s при скромных kB/s и маленьком rareq-sz - тоже норма. Под разную нагрузку - разные узкие места.
  • Забывают, что await включает ожидание в очереди. Большой await при большой aqu-sz часто значит не "диск медленный", а "вы шлёте на него больше, чем он тянет". Иногда лечится не заменой диска, а уменьшением параллелизма в приложении или числа воркеров.
  • Доверяют среднему await и не видят хвоста. Средняя в норме, а p99 ужасный - это и есть случай для biolatency.
Мини-лаба: проверь руками прямо сейчас
  • Сначала узнай тип своего диска:

    Код: Выделить всё

    lsblk -d -o NAME,ROTA,TRAN,MODEL
    - ROTA=1 это HDD, ROTA=0 это SSD/NVMe, TRAN покажет nvme/sata.
  • Открой два терминала. В первом запусти

    Код: Выделить всё

    iostat -xz 1
    и оставь крутиться.
  • Во втором создай нагрузку на запись мимо кэша (осторожно, файл займёт место, потом удали):

    Код: Выделить всё

    dd if=/dev/zero of=/tmp/iotest.bin bs=1M count=4096 oflag=direct
  • Смотри в iostat: как подскочили wkB/s, w_await, aqu-sz и %util на твоём диске. Запиши w_await до и во время нагрузки, сравни с нормой для своего типа диска.
  • Бонус для тех, у кого есть eBPF: параллельно запусти

    Код: Выделить всё

    sudo biolatency-bpfcc 5 1
    и посмотри на гистограмму задержек за время теста - есть ли хвост.
  • Удали файл:

    Код: Выделить всё

    rm /tmp/iotest.bin
Контрольные вопросы
  • Какая колонка iostat - главный сигнал задержки, в каких единицах она измеряется и что в неё входит, кроме времени самого диска?
  • Почему %util не годится как индикатор насыщения для NVMe, SSD и RAID, и на что смотреть вместо него?
  • Чем iowait в top отличается от await в iostat, и какой более честный показатель давления I/O появился в современных ядрах?
  • Что показывает biolatency и в каком случае iostat его не заменит?
Что запомнить

Рабочая команда - iostat -xz 1, читаем со второго блока. await (а лучше r_await/w_await) - это время ожидания запроса глазами приложения, главный показатель здоровья диска: единицы-десятки мс для HDD, доли мс для SATA SSD, ещё меньше для NVMe. %util честен только для старых HDD; на SSD/NVMe/RAID вместо него смотри связку await плюс aqu-sz - растут вместе, вот это насыщение. iowait в top и /proc/pressure/io - повод запустить iostat, а не диагноз сам по себе. А когда нужна правда про хвост задержек и виновника - это уже работа для eBPF: biolatency и biosnoop.
👍1 ❤️2 🔥1 😄 🤔
Аватара пользователя
BashAndy
Сообщения: 1
Зарегистрирован: 26 май 2026, 15:40

Re: Диагностика диска: iostat и чтение await, %util

Сообщение BashAndy »

Спасибо, наконец-то дошло чем iowait отличается от await. Всегда думал что 100% util это всё, приехали - а оно вон как на nvme. И про /proc/pressure/io не знал, удобная штука.
👍2 ❤️1 🔥 😄 🤔
Аватара пользователя
fuzzi
Сообщения: 1
Зарегистрирован: 15 май 2026, 00:39

Re: Диагностика диска: iostat и чтение await, %util

Сообщение fuzzi »

А подскажите, у меня на проде sata ssd стабильно w_await около 6-8 мс под бэкапом, aqu-sz в районе 1.5. Это уже повод паниковать или норм пока await не растёт? И стоит ли сразу biolatency гонять или рано?
👍 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Подсистема ввода-вывода: путь запроса от приложения до диска
Следующая глава →
Кто грузит диск: iotop и атрибуция io процессам

Все главы курса «Диагностика и производительность Linux: логи, strace, perf и eBPF»

Поделиться темой: ✈ Telegram VK
Похожие запросы: как посмотреть сколько памяти занято в linuxss как посмотреть открытые сокеты и соединенияstrace почему программа висит и тормозитЛоги и диагностика macOSкак посмотреть процессы в linux и убить зависшийчто такое load average в linux и какое значение нормальное

Вернуться в «Диагностика и производительность Linux: логи, strace, perf и eBPF»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость