Диагностика: load average, память, диск и открытые файлы

Живая часть секции Linux: интервьюер описывает симптом и смотрит, в каком порядке вы будете искать причину.

Вопрос: «На сервере load average: 12.4. Это плохо? Что вы будете делать дальше?»

Что на самом деле проверяет интервьюер

Проверяют не знание команд, а методику. Кандидат уровня junior отвечает «12 — это много, нужно перезагрузить». Кандидат уровня middle сначала спрашивает, сколько на машине ядер, а потом выясняет природу нагрузки: CPU, диск или блокировки. Умение задать уточняющий вопрос здесь ценится выше готового ответа.

Развёрнутый ответ: что такое load average

Load average — это среднее число процессов, которые либо выполняются на CPU, либо ждут его, либо находятся в состоянии непрерываемого ожидания ввода-вывода (статус D). Последний пункт — специфика Linux, и именно про него любят спрашивать. Три числа — усреднение за 1, 5 и 15 минут; сравнивать их между собой полезнее, чем смотреть на абсолютное значение.

uptime
#  15:04:21 up 42 days,  load average: 12.40, 8.15, 4.02

nproc      # сколько ядер
# 8

Интерпретация: 12.4 при 8 ядрах — перегрузка примерно в полтора раза, очередь растёт (1 минута заметно больше 15 минут). То же значение при 16 ядрах — спокойная жизнь. Правило: сравнивайте load с числом ядер и смотрите на динамику.

Дальше: отделяем CPU от диска

Высокий load при низком потреблении CPU почти всегда означает, что процессы ждут диск или сеть.

top -b -n1 | head -5
# %Cpu(s):  4.1 us,  1.2 sy,  0.0 ni, 12.0 id, 82.3 wa,  0.0 hi,  0.4 si

Ключевой столбец — wa (iowait). 82% означает: процессор простаивает, все ждут диск. Значит, дело не в коде, а в хранилище — и дальше идём в iostat -x 1 или ищем процесс, который жжёт диск:

ps -eo pid,stat,comm | awk '$2 ~ /D/'    # кто застрял в непрерываемом ожидании
iostat -x 1 3                            # утилизация и await по устройствам
pidstat -d 1                             # запись/чтение по процессам

Если же us (user) под 90%, причина в вычислениях: смотрим top, сортируем по CPU (клавиша P), находим виновника.

Вопрос 2: «No space left on device», но df показывает свободное место

Один из самых частых практических вопросов. Есть три классических объяснения, и хороший кандидат называет все три.

Причина 1: закончились inode

Файловая система хранит метаданные файлов в inode, и их количество фиксируется при форматировании. Миллионы мелких файлов (сессии, кэш, необработанные письма) исчерпают inode, когда байт ещё полно.

df -h        # места вроде хватает
df -i        # а вот здесь IUse% = 100%

# Filesystem      Inodes  IUsed IFree IUse% Mounted on
# /dev/sda1      1310720 1310720     0  100% /

# ищем каталог-виновник
for d in /var/*; do echo "$(find $d -xdev | wc -l) $d"; done | sort -rn | head

Причина 2: удалённый файл, который держит процесс

Классика: логи удалили через rm, но приложение по-прежнему держит дескриптор открытым. Место не освободится, пока процесс не закроет файл или не перезапустится.

lsof +L1        # файлы с нулём ссылок, но открытые
# COMMAND   PID  USER  FD  SIZE  NLINK  NODE NAME
# nginx    1042  root  5w  9.8G      0  1337 /var/log/nginx/access.log (deleted)

# правильное решение — не rm, а ротация:
truncate -s 0 /var/log/nginx/access.log
# либо перезагрузить дескрипторы: kill -USR1 $(cat /run/nginx.pid)

Причина 3: место занято на другой файловой системе

Вы смотрите df -h /, а приложение пишет в /var/lib/docker, смонтированный отдельным разделом. Всегда проверяйте df -h целиком и монтирования через findmnt. Отдельный подвох — заполненный /tmp в tmpfs: он живёт в оперативной памяти.

Вопрос 3: права доступа не пускают приложение

Быстрый блиц, который часто идёт следом. Права записываются тремя восьмеричными цифрами: владелец, группа, остальные, где r=4, w=2, x=1. 755 — владелец делает всё, остальные читают и выполняют. 644 — обычный файл конфигурации.

Главная ловушка: для каталога бит x означает не «выполнить», а «войти внутрь». Каталог с правами 644 нельзя открыть, даже если файлы внутри читаемы всем — отсюда типичная ошибка Permission denied при формально верных правах на сам файл.

namei -l /var/www/app/config.yml    # проверяет права на КАЖДЫЙ элемент пути
sudo -u www-data cat /var/www/app/config.yml   # проверка от имени сервиса

chmod 750 /var/www/app       # каталогу нужен x
chown -R app:app /var/www/app

Если права выглядят корректно, а доступа нет — вспомните про SELinux или AppArmor: смотрите getenforce и ausearch -m avc -ts recent.

Типичные ошибки кандидатов

  • Оценивают load average без учёта количества ядер и без взгляда на iowait.
  • Считают, что высокий load всегда означает загруженный процессор — забывают про состояние D.
  • При «No space left» проверяют только df -h и не смотрят df -i и lsof +L1.
  • Удаляют логи через rm вместо ротации или truncate, а потом удивляются, что место не вернулось.
  • Ставят chmod 777 «чтобы точно заработало» — на собеседовании это сразу минус.

Как ответить кратко (20–30 секунд)

«Сначала уточню, сколько на сервере ядер: 12.4 при 8 ядрах — перегрузка, при 32 — норма. Потом посмотрю в top на распределение: если высокий iowait, проблема в диске, иду в iostat и ищу процессы в состоянии D; если высокий user — ищу прожорливый процесс в top. Про диск отдельно помню, что при ошибке «No space left» надо проверять не только df -h, но и df -i на inode, и lsof +L1 на удалённые, но открытые файлы.»

Проверьте себя
1. Load average 12.4 при 16 ядрах, iowait 80%, CPU user 5%. Наиболее вероятная причина?
AПроцессор перегружен вычислениями
BПроцессы ждут дисковый ввод-вывод, узкое место — хранилище
CНе хватает оперативной памяти и начался OOM
DСлишком много зомби-процессов
2. Приложение пишет «No space left on device», а df -h показывает 40% свободного места. Что проверить в первую очередь?
AОбъём swap
Bdf -i (свободные inode) и lsof +L1 (удалённые, но открытые файлы)
CЗначение load average
DКоличество открытых TCP-соединений
3. Файл /var/www/app/config.yml имеет права 644 и владельца app:app, но сервис от пользователя app получает Permission denied. Что вероятнее всего не так?
AФайлу не хватает бита выполнения
BУ одного из каталогов в пути нет бита x, который для каталога означает право входа внутрь
CПрава 644 недействительны для YAML-файлов
DНужно выставить 777 на файл