Ты замечаешь, что приложение тормозит, а пользователи жалуются. Открываешь df — вроде место есть, а top показывает, что процессор не загружен. Что дальше? Скорее всего, проблема в дисковой подсистеме. Деградация дисков часто маскируется под сетевые задержки или нехватку CPU, а когда количество серверов перевалило за сотню, ручные правки конфигов и bash-скрипты перестают спасать. Чтобы не тушить пожары вручную (особенно в 3 часа ночи), нужно уметь быстро диагностировать проблему: отличать нехватку места от перегрузки IOPS, находить процессы, создающие аномальную нагрузку, и проверять реальную производительность диска. В этой статье разберём практический набор инструментов — от классических df, iostat до специализированных fio, iotop, pidstat и ioping — с примерами команд, интерпретацией выводов, типовыми ошибками и чек-листами для реальных сценариев в российской корпоративной среде.

Почему мониторинг дисков критичен для надёжности системы

В современной инженерии надёжности (SRE) дисковая подсистема — это не просто «место для файлов». Это ключевой ресурс, от которого зависит время отклика приложений (особенно для баз данных, логов, кэшей), стабильность работы контейнеров и Kubernetes (поды «падают» при нехватке места или при латентности выше допустимой), корректность бэкапов и резервного копирования (медленные диски приводят к провалам в окнах бэкапа), а также финансовая эффективность (FinOps): в облаках IOPS и throughput часто тарифицируются отдельно, и неоптимальное использование ведёт к лишним расходам. В гибридных средах, где локальное железо соседствует с облаком, разница в latency между локальным SSD и сетевым хранилищем может стать неприятным сюрпризом, если не контролировать показатели.

Типичные индикаторы проблем с дисками:

Индикатор Что означает
Высокий %util в iostat Диск почти постоянно загружен, очередь операций растёт
Высокий await и svctm Операции ввода-вывода выполняются медленно, возможна проблема с контроллером или самим диском
Рост latency (задержки) Приложения ждут ответа от диска, что ведёт к замедлению всей системы
Нехватка места (df показывает 95–100%) Риск падения служб, невозможность записи логов, сбой бэкапов
Высокая нагрузка на inodes Нехватка файловых дескрипторов, даже если место свободно
Аномальная нагрузка от одного процесса (iotop) «Сосед» по серверу съедает все IOPS, другие службы страдают

Важно: IOPS (Input/Output Operations Per Second) — это количество операций ввода-вывода в секунду. Для дисков это не просто скорость в МБ/с, а именно число операций, особенно критично для случайных операций (randread/randwrite) с малым блоком (4K). В базах данных, системах логирования и кэшировании IOPS часто важнее throughput. На практике я не раз видел, как приложение «лежало» из-за того, что диск физически мог выдать 100 МБ/с последовательного чтения, но захлёбывался на тысячах случайных запросов по 4К.

Установка необходимых утилит: sysstat, fio, ioping, iotop

Большинство инструментов мониторинга дисков в Linux не входят в базовый набор и требуют установки дополнительных пакетов. В корпоративных средах это часто приходится согласовывать с безопасниками, но без них диагностика вслепую — это как тушить пожар без воды. Ниже — инструкции для распространённых дистрибутивов, используемых в России (Ubuntu, Debian, CentOS, RHEL, Alt Linux).

Пакет sysstat (iostat, iotop, pidstat)

Утилита iostat — стандарт индустрии для мониторинга IOPS и дисковой активности в реальном времени. Она входит в пакет sysstat, который также предоставляет iotop, pidstat, mpstat.

Установка:

# Ubuntu/Debian
sudo apt update && sudo apt install sysstat -y

# CentOS/RHEL
sudo yum install sysstat -y

# Alt Linux
sudo apt-get install sysstat

После установки нужно активировать сбор статистики (в некоторых системах по умолчанию отключён). В Debian/Ubuntu для этого достаточно раскомментировать строку ENABLED="true" в /etc/default/sysstat и перезапустить сервис: sudo systemctl enable sysstat && sudo systemctl start sysstat. В RHEL/CentOS аналогично редактируется /etc/sysconfig/sysstat.

Пакет fio (тестирование производительности)

fio — нагрузочный тестер дисков, позволяющий замерить реальную производительность в различных сценариях: randread, randwrite, seqread, seqwrite, с разным размером блока и глубиной очереди. Без него ты не узнаешь, на что способен диск в идеальных условиях, а значит, не сможешь отличить конфигурационную проблему от физической деградации.

Установка:

# Ubuntu/Debian
sudo apt install fio -y

# CentOS/RHEL (EPEL)
sudo yum install epel-release -y && sudo yum install fio -y

# Alt Linux
sudo apt-get install fio

Пакет ioping (замер latency)

ioping — простая утилита для замера latency (задержки) диска, аналог ping для дисковых операций. Когда приложение жалуется на «тормоза», а iostat показывает высокий await, ioping поможет подтвердить, что проблема именно на уровне дискового ввода-вывода.

Установка:

# Ubuntu/Debian
sudo apt install ioping -y

# CentOS/RHEL (EPEL)
sudo yum install ioping -y

# Alt Linux
sudo apt-get install ioping

Пакет blktrace (btrace, fatrace) и strace

Для детального анализа того, что именно пишет процесс на диск, используются:

  • btrace (из пакета blktrace) — трассировка блочных операций;
  • fatrace — трассировка файловых обращений через inotify;
  • strace — трассировка вызовов системы, включая write.

Установка:

# Ubuntu/Debian
sudo apt install blktrace fatrace strace -y

# CentOS/RHEL (EPEL)
sudo yum install blktrace strace -y   # fatrace может отсутствовать в базовых репозиториях

# Alt Linux
sudo apt-get install blktrace fatrace strace

Мониторинг дискового пространства: df, du, lsblk, find

Первый шаг в диагностике — понять, сколько места свободно, и где оно «съедается». На практике часто df показывает 80%, но df -i показывает 99% — это типичная ловушка с мелкими файлами, особенно в почтовых серверах или системах с большим количеством временных файлов.

df — общая картина по файловым системам

df (disk free) показывает использование места по файловым системам.

df -h

Пример вывода:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        50G   20G   28G  42% /
/dev/sdb1       200G  150G   50G  75% /data

Ключевые поля:

  • Size — общий размер;
  • Used — использовано;
  • Avail — свободно;
  • Use% — процент использования;
  • Mounted on — точка монтирования.

Типовая ошибка: полагаться только на df и не проверять inodes. Сколько раз я видел сервер, упавший из-за нехватки inodes при 30% свободного места — не сосчитать.

Проверка inodes: df -i

Inodes — это структуры, описывающие файлы. Если inodes исчерпаны, нельзя создать новый файл, даже если место свободно.

df -i

Пример:

Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/sda1      3276800 3200000 76800   98% /

Если IUse% > 90% — критическая ситуация: нужно искать мелкие файлы и удалять их. Обычно это кэши, сессионные файлы или старые логи, разбитые на тысячи крошечных кусочков.

du — размер директорий и файлов

du (disk usage) показывает размер конкретных директорий и файлов.

du -sh /var/log /home/* /tmp

Пример поиска логов, которые «съели» место:

du -ah /var/log | sort -rh | head -20

Эта команда часто становится первым, что я запускаю, когда мониторинг орёт о заполнении раздела.

lsblk — структура дисков и разделов

lsblk показывает физические диски, разделы, точки монтирования.

lsblk -f

Пример:

NAME   FSTYPE LABEL UUID                                 MOUNTPOINT
sda
├─sda1 ext4         12345678-1234-1234-1234-123456789abc /
└─sda2 swap         87654321-4321-4321-4321-cba987654321 [SWAP]
sdb
└─sdb1 xfs          9abcdef0-1234-5678-9abc-def012345678 /data

find — поиск файлов по размеру и времени

Для поиска крупных файлов или старых логов:

# Найти файлы больше 100 МБ
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null

# Найти и удалить файлы старше 30 дней в /var/log
find /var/log -type f -mtime +30 -delete

Мониторинг IOPS и дисковой активности: iostat, iotop, pidstat

Когда место свободно, но система «тормозит», проблема часто в IOPS и latency. Здесь в бой вступают утилиты из пакета sysstat.

iostat — основная утилита мониторинга IOPS

iostat показывает статистику ввода-вывода по дискам в реальном времени. Если доводилось тушить пожар в 3 часа ночи, то понимаешь, что iostat -x 1 — это твой лучший друг, но интерпретировать его нужно с умом.

Базовый запуск:

iostat -x -t -m 1

Ключевые параметры:

  • -x — расширенная статистика (включает все метрики);
  • -t — выводить время для каждой порции замеров;
  • -m — результаты в МБ/с (вместо КБ);
  • -k — результаты в КБ/с;
  • -d — только диски (без устройств);
  • -p — только указанные устройства (например, -p sda).

Пример вывода:

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.10     5.20    2.50    8.30     0.10     0.30    45.50     0.05    5.20    2.10    6.80   1.20  12.50

Интерпретация ключевых метрик:

Метрика Что означает Критично
tps Операций в секунду (reads + writes) > 1000 для SSD может быть нормально, для HDD — уже нагрузка
r/s, w/s Число операций чтения/записи в секунду Высокие значения при малом блоке = нагрузка на IOPS
rkB/s, wkB/s Скорость чтения/записи в КБ/с Важно для throughput, но не заменяет IOPS
avgrq-sz Средний размер запроса в секторах (512 байт) Малый размер = много мелких операций (IOPS-нагрузка)
avgqu-sz Средняя длина очереди операций > 1 — очередь растёт, диск не успевает
await Среднее время ожидания операции (мс) > 10–20 мс для SSD — проблема, > 50 мс для HDD — критично
svctm Среднее время обслуживания операции (мс) Высокое значение = диск работает медленно
%util Процент загрузки диска > 80–90% — диск почти постоянно загружен, риск latency

Типовая ситуация:

  • %util = 95%, await = 25 мс, avgqu-sz = 3 → диск перегружен, очередь растёт, latency высокая.
  • r/s = 500, w/s = 100, rkB/s = 2000, wkB/s = 400 → много мелких операций чтения, IOPS-нагрузка, throughput низкий.

Для SSD %util не всегда показатель: они могут обрабатывать несколько операций параллельно, поэтому значение 100% ещё не означает, что диск упёрся в потолок. Ориентируйся на await и avgqu-sz.

Запуск в режиме реального времени с watch:

watch -n 1 iostat -x -t -m

Это обновляет вывод каждую 1 секунду, удобно для быстрой диагностики в реальном времени.

iotop — мониторинг нагрузки от процессов

iotop показывает нагрузку на диск от отдельных процессов, аналог top для дисковых операций. Без него ты видишь только общую картину, а не то, какой конкретный процесс превратился в «пожирателя IOPS».

Базовый запуск:

sudo iotop

Оптимальные ключи для продакшена:

sudo iotop -obPat

Ключи:

  • -o — выводить только процессы с активной нагрузкой;
  • -b — режим без интерактивности (удобно для скриптов);
  • -p — выводить PID;
  • -a — показывать накопленную нагрузку;
  • -t — выводить время.

Пример вывода:

Total DISK READ:       0.00 B/s | Total DISK WRITE:      15.50 M/s
Current DISK READ:     0.00 B/s | Current DISK WRITE:    12.30 M/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
 1234 be/4 root        0.00 B/s   15.50 M/s  0.00 %  0.00 % mysqld

Ключевые поля:

  • READ — скорость чтения от процесса;
  • WRITE — скорость записи;
  • COMMAND — имя процесса.

Типовая ошибка: не проверять iotop и полагаться только на iostat. В результате не видно, кто именно создаёт нагрузку. На одном из проектов мы так потратили час, пока не нашли, что бекап-агент писал логи в бесконечном цикле.

pidstat — статистика по процессам с детализацией

pidstat — утилита из sysstat для статистики по процессам, включая дисковую нагрузку. Она позволяет конкретизировать нагрузку по PID, что удобно для отладки конкретных служб.

Базовый запуск:

pidstat -d 1

Запуск для конкретного PID:

pidstat -d -p 1234 1

Пример вывода:

Linux 5.15.0-91-generic (hostname)      01/17/2024      _x86_64_        (4 CPU)
05:30:01 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
05:30:02 PM     0      1234      0.00    300.00      0.00  mysqld

Ключевые поля:

  • tps — операции в секунду;
  • kB_read/s, kB_wrtn/s — скорость чтения/записи;
  • COMMAND — имя процесса.

fatrace — трассировка файловых обращений

fatrace показывает, какие файлы открываются и записываются процессами, через inotify. Полезно, когда нужно понять, куда именно процесс пишет данные.

Базовый запуск:

sudo fatrace -f W

Запись в лог:

sudo fatrace -f W -o /tmp/fatrace.log

Пример вывода:

mysqld(1234): W /var/lib/mysql/ibdata1
backup(5678): W /mnt/backup/db_backup.tar.gz

Важно: fatrace работает только с файлами, которые подписаны на inotify, и не показывает все операции. Это скорее быстрый способ найти «горячие» файлы, но не замена полноценной трассировке.

strace — трассировка вызовов write

strace позволяет просмотреть, какие вызовы write делает процесс. Использовать только для временной отладки, так как он сильно замедляет процесс.

sudo strace -e trace=write -p 1234

Пример вывода:

write(3, "ERROR: table not found\n", 22) = 22
write(4, "INSERT INTO logs ...", 20) = 20

Замер реальной производительности диска: fio

iostat показывает текущую нагрузку, но не отвечает на вопрос: «Какой максимум IOPS и throughput диск может выдать?». Для этого используется fio — нагрузочный тестер. Это ключевой инструмент, когда нужно доказать, что «железо» не соответствует ожиданиям, или проверить, не деградировал ли диск после месяцев эксплуатации.

Установка и базовые сценарии

После установки (см. выше) можно запускать тесты. В продакшене такие тесты лучше проводить в периоды минимальной нагрузки или на тестовом стенде, чтобы не уронить сервисы.

Простой тест случайной записи (randwrite):

fio --name=randwrite --ioengine=libaio --direct=1 --rw=randwrite --bs=4k --size=1G --numjobs=1 --time_based --runtime=60 --iodepth=32

Ключевые параметры:

  • --name — имя теста;
  • --ioengine=libaio — механизм ввода-вывода (для Linux);
  • --direct=1 — прямой доступ (без буферизации);
  • --rw=randwrite — случайная запись;
  • --bs=4k — размер блока 4 КБ (стандарт для IOPS);
  • --size=1G — размер теста;
  • --numjobs=1 — число параллельных задач;
  • --time_based --runtime=60 — тест 60 секунд;
  • --iodepth=32 — глубина очереди.

Пример вывода (ключевые метрики):

Jobs: 1 (f=1): [w(1)][100.0%][w=123MiB/s][w=31.5k IOPS][eta 00m:00s]
  write: IOPS=31.5k, BW=123MiB/s (129MB/s)(7380MiB/60001msec)
    lat (usec): min=5, max=1500, avg=10.50, stdev= 5.20
  • IOPS — операции в секунду;
  • BW — throughput в МБ/с;
  • Latency — средняя задержка.

Тест случайного чтения (randread):

fio --name=randread --ioengine=libaio --direct=1 --rw=randread --bs=4k --size=1G --numjobs=1 --time_based --runtime=60 --iodepth=32

Тест смешанного чтения/записи (randrw, 75/25):

fio --name=randrw --ioengine=libaio --direct=1 --rw=randrw --rwmixread=75 --bs=4k --size=1G --numjobs=1 --time_based --runtime=60 --iodepth=32

Тест последовательной записи (seqwrite):

fio --name=seqwrite --ioengine=libaio --direct=1 --rw=write --bs=1M --size=1G --numjobs=1 --time_based --runtime=60 --iodepth=32

Тест последовательного чтения (seqread):

fio --name=seqread --ioengine=libaio --direct=1 --rw=read --bs=1M --size=1G --numjobs=1 --time_based --runtime=60 --iodepth=32

Сравнение сценариев: таблица

Сценарий Команда Что измеряет Критично для
randwrite --rw=randwrite Случайная запись Базы данных, логирование
randread --rw=randread Случайное чтение Кэши, выборки из БД
randrw (75/25) --rw=randrw --rwmixread=75 Смешанная нагрузка Веб-серверы, микросервисы
seqwrite --rw=write --bs=1M Последовательная запись Бэкапы, архивы
seqread --rw=read --bs=1M Последовательное чтение Восстановление, архивы

Важно: для IOPS-нагрузки использовать малый блок (4K), для throughput — большой (1M).

Замер latency через ioping

ioping — простая утилита для замера latency (задержки) диска.

ioping -c 10 /tmp

Пример вывода:

4 KiB from /tmp (ext4 /dev/sda1): request=1 time=0.5 ms
4 KiB from /tmp (ext4 /dev/sda1): request=2 time=0.7 ms
--- /tmp (ext4 /dev/sda1) ioping statistics ---
10 requests completed in 9.5 ms, 40 KiB read, 1.05 k iops, 4.11 MiB/s
min/avg/max/mdev = 0.5 ms / 0.95 ms / 1.8 ms / 0.4 ms
  • min, avg, max — минимальная, средняя и максимальная задержка;
  • stdev — стандартное отклонение.

Критично: для SSD avg < 1 мс, для HDD — 5–10 мс. Если avg > 10 мс для SSD — проблема с диском или контроллером. На практике сталкивался, когда NVMe-диск внезапно начал выдавать 15 мс — оказалось, что контроллер перегревался и троттлил.

Практические сценарии: диагностика проблем с дисками

Ниже — реальные кейсы, с которыми сталкиваются системные администраторы в России, и пошаговые инструкции для диагностики.

Сценарий 1: Сервер «тормозит», но место свободно

Проблема: df показывает 30% использования, но приложения «тормозят», latency высокая.

Шаги диагностики:

  1. Проверить iostat:
    iostat -x -t -m 1

    Если %util > 80%, await > 10 мс, avgqu-sz > 1 → диск перегружен.

  2. Найти процесс с наибольшей нагрузкой:
    sudo iotop -obPat

    Если один процесс (например, mysqld) съедает 90% WRITE → проблема в этой службе.

  3. Проверить latency:
    ioping -c 10 /var/lib/mysql

    Если avg > 10 мс для SSD → проблема с диском.

  4. Запустить тест fio (вне пиковой нагрузки):
    fio --name=randread --ioengine=libaio --direct=1 --rw=randread --bs=4k --size=1G --numjobs=1 --time_based --runtime=60 --iodepth=32

    Если IOPS ниже ожидаемого для типа диска (например, < 5000 для SSD) → диск деградировал или контроллер не справляется.

Решение:

  • Оптимизировать нагрузку (например, изменить размер блока в БД, уменьшить частоту логирования);
  • Перенести нагрузку на отдельный диск;
  • Заменить диск на более быстрый (NVMe вместо SATA).

Помню случай, когда сервер на SSD показывал высокий await, а fio подтвердил деградацию — пришлось срочно мигрировать на новый диск, потому что запасного не было, а бизнес-процессы встали.

Сценарий 2: Нехватка места в /var/log

Проблема: df показывает 98% в /var, службы не пишут логи.

Шаги диагностики:

  1. Найти крупные файлы:
    du -ah /var/log | sort -rh | head -20
  2. Удалить старые логи:
    find /var/log -type f -name "*.log" -mtime +30 -delete
  3. Проверить inodes:
    df -i /var

    Если IUse% > 90% → много мелких файлов, нужно искать и удалять.

Решение:

  • Настроить logrotate для автоматического удаления старых логов;
  • Перенести логи на отдельный диск;
  • Увеличить размер диска или добавить новый.

Сценарий 3: Высокая нагрузка на inodes

Проблема: df -i показывает 98% inodes, но место свободно.

Шаги диагностики:

  1. Найти мелкие файлы:
    find / -type f -size -1k -exec ls -la {} \; 2>/dev/null | head -50
  2. Удалить ненужные мелкие файлы (с осторожностью):
    find /path/to/dir -type f -empty -delete

Решение:

  • Увеличить количество inodes при создании файловой системы (например, mkfs.ext4 -i 16384);
  • Перенести мелкие файлы на отдельный диск с большим количеством inodes.

Сценарий 4: Аномальная нагрузка от одного процесса

Проблема: iotop показывает, что один процесс (например, backup) съедает все WRITE.

Шаги диагностики:

  1. Проверить, что именно пишет процесс:
    sudo fatrace -f W | grep backup
  2. Трассировать вызовы write:
    sudo strace -e trace=write -p $(pgrep backup)

Решение:

  • Оптимизировать бэкап (например, использовать --ignore-fs для определённых файлов);
  • Перенести бэкап на отдельный диск;
  • Уменьшить частоту бэкапа.

Чек-лист: мониторинг дисков на Linux-сервере

Ежедневный чек-лист:

  • df -h — проверить использование места;
  • df -i — проверить inodes;
  • iostat -x -t -m 5 — проверить IOPS и latency;
  • iotop -obPat — найти процессы с высокой нагрузкой;
  • du -sh /var /home /tmp — проверить размер ключевых директорий.

Еженедельный чек-лист:

  • find /var/log -type f -mtime +30 -delete — удалить старые логи;
  • fio — тест производительности диска (если есть подозрения);
  • ioping — замер latency (если есть проблемы с откликом).

При подозрении на проблему:

  • iostat -x -t -m 1 2 — динамика в реальном времени;
  • pidstat -d 1 — статистика по процессам;
  • fatrace -f W — трассировка файловых обращений;
  • strace -e trace=write -p PID — трассировка вызовов write.

FAQ: частые вопросы по мониторингу дисков и IOPS

Чем отличается IOPS от throughput?

IOPS — количество операций ввода-вывода в секунду (операций, не байт). Throughput — скорость в МБ/с. Для мелких операций (4K) IOPS важнее, для крупных (1M) — throughput.

Какой размер блока использовать в fio для замера IOPS?

Для замера IOPS использовать 4K (стандарт для баз данных, логирования). Для замера throughput1M.

Почему %util в iostat высокий, но await низкий?

Это может означать, что диск загружен, но операции выполняются быстро (например, SSD с низкой latency). Если await растёт — проблема с диском или контроллером.

Как проверить, что диск деградировал?

Запустить тест fio и сравнить IOPS с эталонным значением для типа диска. Если IOPS ниже ожидаемого — диск деградировал.

Можно ли использовать iostat для мониторинга в реальном времени?

Да, iostat 1 обновляет вывод каждые 1 секунду. Для динамики использовать watch -n 1 iostat -xk.

Почему iotop показывает нагрузку, но iostat — нет?

iotop показывает нагрузку от процессов, iostatобщую нагрузку по дискам. Если нагрузка от одного процесса, iotop её покажет, iostat — общую.

Как настроить автоматический мониторинг дисков?

Использовать Zabbix, Prometheus + Node Exporter, или облачные панели (например, Cloud4Y, AWS CloudWatch). Для ручного мониторинга — скрипты с df, iostat, iotop.

Вывод: от ручного тушения пожаров к автоматизированному мониторингу

Мониторинг дискового пространства и IOPS — не опция, а обязательная практика для современного системного администратора, который переходит от ручного управления к автоматизированным пайплайнам и облачным архитектурам. iostat, fio, iotop, pidstat, ioping — это не просто утилиты, а инструменты инженерии надёжности, которые позволяют быстро находить узкие места в дисковой подсистеме, отличать нехватку места от перегрузки IOPS, находить процессы, создающие аномальную нагрузку, проверять реальную производительность диска и предотвращать падения служб из-за деградации дисков.

Современный админ — это инженер по надёжности, который автоматизирует всё, включая собственные задачи. Мониторинг дисков — один из первых шагов к построению отказоустойчивых систем, которые не падают под нагрузкой. Когда я начинал с классического сисадминства, ручные проверки и bash-скрипты спасали, но с ростом числа серверов пришлось внедрять Ansible, Terraform, Prometheus. Теперь, оглядываясь назад, понимаю: без понимания того, что происходит с дисками, невозможен ни грамотный FinOps, ни надёжный Kubernetes, ни спокойный сон по ночам.