Диагностика истощения ресурсов Linux: ЦП, память и дисковое пространство

Диагностируйте истощение ЦП, памяти и диска в Linux с помощью практических команд, безопасных шагов по очистке и проверок первопричин.

Диагностика истощения ресурсов Linux: ЦП, память и дисковое пространство

Когда на сервере Linux заканчиваются ресурсы ЦП, памяти или дискового пространства, первый симптом обычно расплывчат: сайт работает медленно, SSH зависает после входа, развертывания не удаются или служба постоянно перезапускается. Самый быстрый способ справиться с инцидентом — определить, какой ресурс исчерпан, а затем найти процесс или файловую систему, стоящую за этим.

Сначала выполняйте наименее рискованные проверки. Команды только для чтения, такие как top, free, df, du, vmstat и journalctl, дают вам картину без изменения машины. Убийство процессов и удаление файлов могут быть необходимы, но это не диагностика.

Определение виновника: мониторинг системных ресурсов

Прежде чем вы сможете устранить проблему истощения ресурсов, вам необходимо определить, какой ресурс используется чрезмерно и какой процесс за это отвечает. Linux предоставляет богатый набор инструментов командной строки для этой цели.

Мониторинг использования ЦП

Высокая загрузка ЦП может сделать вашу систему медленной и не отвечающей. Часто это вызвано вышедшим из-под контроля процессом, требовательным приложением или неэффективным скриптом.

  • top: Это незаменимый монитор системы в реальном времени. Он отображает динамический список процессов, отсортированных по умолчанию по использованию ЦП. Вы можете увидеть общую загрузку ЦП, использование памяти и детали отдельных процессов.

    top
    

    Внутри top нажмите 1, чтобы увидеть использование отдельных ядер ЦП. Нажмите P, чтобы отсортировать по использованию ЦП. Ищите процессы, постоянно потребляющие высокий процент ЦП.

  • htop: Улучшенная интерактивная версия top. Ее часто предпочитают за удобство использования, цветной вывод и более легкую навигацию.

    htop
    

    Как и top, htop позволяет сортировать по использованию ЦП и предоставляет подробную информацию о процессах.

  • mpstat: Часть пакета sysstat, mpstat предоставляет подробную статистику ЦП, включая использование на процессор, количество прерываний и переключения контекста.

    mpstat -P ALL 1
    

    Эта команда будет отображать статистику ЦП для всех ядер каждую секунду.

Также проверьте среднюю нагрузку по сравнению с количеством ЦП:

uptime
nproc

Средняя нагрузка 8 означает совершенно разное на 2-ядерной ВМ и на 32-ядерном хосте. Нагрузка также включает задачи, ожидающие непрерываемого ввода-вывода, поэтому высокая средняя нагрузка при низком использовании ЦП может указывать на проблемы с диском или сетевым хранилищем.

Мониторинг использования памяти

Когда в системе заканчивается доступная оперативная память и пространство подкачки, она начинает использовать дисковое пространство в качестве виртуальной памяти, что значительно медленнее и приводит к серьезной деградации производительности.

  • free -h: Отображает общее количество свободной и используемой физической памяти и памяти подкачки в системе, а также буферы и кэши, используемые ядром. Флаг -h делает вывод удобочитаемым (например, МБ, ГБ).

    free -h
    

    Обратите внимание на available (доступную) память и used (используемое) пространство подкачки. Высокое использование подкачки указывает на недостаток оперативной памяти.

  • top / htop: Обе утилиты показывают использование памяти на процесс. Ищите процессы с высоким значением %MEM.

  • vmstat: Сообщает статистику виртуальной памяти. Может показывать информацию о процессах, памяти, подкачке страниц, блочном вводе-выводе, прерываниях и активности ЦП.

    vmstat 5
    

    Эта команда будет сообщать статистику каждые 5 секунд. Посмотрите на столбцы si (подкачка в) и so (подкачка из); высокие значения указывают на значительную подкачку памяти.

Для возможных убийств OOM проверьте журнал ядра:

dmesg -T | grep -i 'killed process'
journalctl -k --since "1 hour ago" | grep -i oom

Убийство OOM меняет инцидент. Немедленный вопрос становится: какой процесс был убит, почему он превысил доступную память и перезапустил ли его systemd или оркестратор.

Мониторинг дискового пространства

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

  • df -h: Сообщает об использовании дискового пространства файловой системы. Флаг -h делает вывод удобочитаемым.

    df -h
    

    Эта команда выведет список всех смонтированных файловых систем и покажет их общий размер, использованное пространство, доступное пространство и точку монтирования. Ищите разделы со 100% использованием или близким к этому.

  • du -sh <directory>: Оценивает использование пространства файлами для заданного каталога. Флаг -s суммирует, а -h делает вывод удобочитаемым.

    du -sh /var/log/*
    

    Используйте это, чтобы найти, какие подкаталоги потребляют больше всего дискового пространства.

Также проверьте использование инодов:

df -ih

Файловая система может иметь свободные гигабайты и все еще не может создавать файлы, если в ней закончились иноды. Это происходит с миллионами крошечных файлов: записи кэша, очереди почты, файлы сессий, артефакты сборки или плохо ротированные журналы.

Решение проблем истощения ресурсов

После того как вы определили проблемный ресурс и offending процесс, вы можете предпринять шаги для решения проблемы.

Решение проблемы высокой загрузки ЦП

  1. Определите процесс: Используйте top или htop, чтобы найти идентификатор процесса (PID), потребляющий много ЦП.
  2. Исследуйте процесс: Определите, что это за процесс. Это пользовательское приложение, системная служба или что-то неожиданное?
    • Легитимное высокое использование: Если легитимное приложение использует много ЦП (например, компиляция программного обеспечения, кодирование видео), возможно, вам нужно подождать его завершения, запланировать его на непиковые часы или обновить оборудование.
    • Вышедший из-под контроля процесс: Если процесс застрял в цикле или непреднамеренно потребляет чрезмерное количество ЦП, вы можете попробовать перезапустить его. Если это не помогает, возможно, вам придется завершить его.
  3. Завершите процесс (Используйте с осторожностью!): Вы можете использовать команду kill для отправки сигналов процессам. Наиболее распространенные сигналы:
    • SIGTERM (15): Вежливо просит процесс завершиться.
    • SIGKILL (9): Принудительно завершает процесс немедленно. Это должно быть крайней мерой, так как не позволяет процессу выполнить очистку.
    # Вежливо завершить процесс с PID 1234
    kill 1234
    
    # Принудительно завершить процесс с PID 1234
    kill -9 1234
    
  4. Проверьте журналы: Изучите системные журналы (например, /var/log/syslog, /var/log/messages, журналы конкретных приложений) на предмет ошибок, связанных с проблемным процессом.
  5. Оптимизируйте приложения/скрипты: Если высокая загрузка ЦП вызвана неэффективным приложением или скриптом, рассмотрите возможность оптимизации кода или конфигурации.

Высокая загрузка ЦП не всегда плоха. Пакетное задание, использующее все ядра в течение короткого времени, может быть нормальным. Однопоточный процесс, застрявший на 100% одного ядра, в то время как запросы стоят в очереди за ним, — это другое дело. Посмотрите на продолжительность, влияние на пользователя и ожидается ли, что процесс будет занят.

Если вам нужно больше контекста перед перезапуском службы, сделайте снимок:

ps -fp <pid>
sudo lsof -p <pid> | head
sudo strace -p <pid> -tt -T -f

Используйте strace осторожно на производственных системах. Это может добавить накладные расходы, но короткий образец часто говорит вам, зациклен ли процесс, ожидает ли файлы, выполняет ли неудачные сетевые вызовы или многократно открывает один и тот же ресурс.

Устранение утечек памяти и истощения

Утечка памяти происходит, когда программа не освобождает память, которая ей больше не нужна, постепенно потребляя всю доступную оперативную память. Это может привести к чрезмерной подкачке и отсутствию реакции системы.

  1. Определите процесс: Используйте top или htop, чтобы найти процессы с высоким потреблением памяти (%MEM) или размером резидентного набора (RSS), которые неуклонно увеличиваются со временем.
  2. Исследуйте процесс: Определите природу приложения. Это известное приложение с потенциальными проблемами с памятью или что-то кастомное?
  3. Перезапустите приложение/службу: Часто простой перезапуск приложения или службы может временно решить проблему утечки памяти, освободив накопленную память.
    # Пример: Перезапуск веб-сервера Apache
    sudo systemctl restart apache2
    
  4. Проверьте мониторинг, специфичный для приложения: Многие приложения (например, веб-серверы, базы данных) имеют свои собственные инструменты мониторинга или журналы, которые могут помочь диагностировать проблемы с памятью.
  5. Проанализируйте дампы памяти: Для критически важных приложений вам может потребоваться включить дампы памяти и использовать инструменты отладки (например, gdb) для анализа состояния памяти при возникновении утечки. Это расширенный шаг устранения неполадок.
  6. Увеличьте пространство подкачки (временная мера): Если вы не можете немедленно устранить утечку, вы можете увеличить пространство подкачки, чтобы обеспечить больше виртуальной памяти. Однако это обходной путь, а не решение.
  7. Модернизация оборудования: Если в вашей системе постоянно не хватает памяти для ее рабочей нагрузки, возможно, вам потребуется добавить больше физической оперативной памяти.

Лучшее исследование памяти отслеживает изменения во времени. Один скриншот top говорит только о том, кто сейчас велик. Утечка — это тренд.

while true; do
  date
  ps -eo pid,comm,rss,%mem --sort=-rss | head -15
  sleep 60
done

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

Для служб systemd проверьте, существуют ли уже ограничения памяти:

systemctl show <service> -p MemoryCurrent -p MemoryMax

Для контейнеров free -h на уровне хоста может выглядеть нормально, в то время как контейнер достигает своего собственного лимита. Проверьте docker stats, kubectl top pod или события оркестратора на предмет убийств OOM.

Управление полными разделами диска

Когда раздел диска заполняется, это может вызвать различные сбои системы. Обычно требуются немедленные действия.

  1. Определите полный раздел: Используйте df -h, чтобы найти раздел(ы), заполненные на 100%.
  2. Найдите большие файлы/каталоги: Используйте du -sh или du -h --max-depth=1 <directory>, чтобы перемещаться по дереву каталогов и найти, что занимает место.
    # Найдите самые большие каталоги в корневом разделе
    sudo du -h --max-depth=1 / | sort -rh
    
    Типичные виновники включают файлы журналов (/var/log), временные файлы (/tmp), кэши пакетов и пользовательские данные.
  3. Очистите файлы журналов: Файлы журналов могут стать очень большими. Вы можете безопасно удалить старые журналы или настроить ротацию журналов (logrotate) для автоматического управления их размером.
    • Удаление старых журналов: Будьте осторожны и убедитесь, что вы не удаляете активные журналы. Вы можете использовать find для удаления файлов старше определенного количества дней.
      # Удалить файлы .log старше 30 дней в /var/log/myapp
      sudo find /var/log/myapp -name "*.log" -type f -mtime +30 -delete
      
    • Ротация журналов: Убедитесь, что logrotate правильно настроен для всех служб, генерирующих журналы. Обычно он запускается ежедневно и обрабатывает архивирование и удаление старых журналов.
  4. Очистите кэш менеджера пакетов: Менеджеры пакетов часто хранят загруженные файлы пакетов. Очистка их может освободить значительное пространство.
    • Debian/Ubuntu (apt):
      sudo apt autoremove
      sudo apt clean
      
    • CentOS/RHEL/Fedora (yum/dnf):
      sudo yum autoremove  # или dnf autoremove
      sudo yum clean all   # или dnf clean all
      
  5. Удалите неиспользуемые пакеты: Удалите программное обеспечение, которое вам больше не нужно.
    • Debian/Ubuntu: sudo apt remove <package_name>
    • CentOS/RHEL/Fedora: sudo yum remove <package_name> или sudo dnf remove <package_name>
  6. Проверьте временные каталоги: Файлы в /tmp часто можно безопасно удалить, особенно после перезагрузки, но будьте осторожны, если приложения активно их используют.
  7. Очистите корзину: Если вы используете среду рабочего стола, проверьте корзины пользователей.
  8. Рассмотрите возможность изменения размера разделов: Если пространство постоянно является проблемой и очистки недостаточно, возможно, вам потребуется изменить размер разделов или добавить больше хранилища. Это более сложная операция, которая может потребовать размонтирования разделов или загрузки из live-среды.

Будьте осторожны с удаленными файлами, которые все еще открыты. df может показывать полную файловую систему даже после того, как вы удалили большой файл журнала, потому что работающий процесс все еще держит дескриптор файла открытым.

sudo lsof +L1

Если удаленный файл все еще удерживается открытым, перезапуск или перезагрузка владеющей службы освобождает пространство. Делайте это намеренно; не перезапускайте базу данных или критическую службу в середине инцидента, не понимая последствий.

Для журналов journal предпочитайте очистку journalctl ручному удалению файлов:

journalctl --disk-usage
sudo journalctl --vacuum-time=14d

Для хостов Docker проверьте журналы контейнеров и неиспользуемые образы:

docker system df
docker ps --size

Не запускайте широкие команды prune вслепую на производственном хосте. Они могут удалить образы, кэш сборки, остановленные контейнеры и сети, которые кто-то ожидал сохранить.

Порядок триажа, который работает под давлением

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

  1. Подтвердите, что хост доступен и не только для чтения:

    uptime
    date
    mount | grep ' ro,'
    
  2. Проверьте ЦП и нагрузку:

    top
    uptime
    
  3. Проверьте память и подкачку:

    free -h
    vmstat 1 5
    
  4. Проверьте дисковое пространство и иноды:

    df -h
    df -ih
    
  5. Проверьте последние ошибки ядра и служб:

    journalctl -p warning..alert --since "30 minutes ago"
    journalctl -k --since "30 minutes ago"
    

Этот порядок быстро выявляет распространенные сбои: насыщение ЦП, штормы подкачки, полные файловые системы, истощение инодов, убийства OOM и ошибки хранилища.

Выбор наименее плохого немедленного исправления

Во время простоя вам может понадобиться краткосрочное исправление до того, как будет готово постоянное.

При истощении ЦП плавный перезапуск службы может быть безопаснее, чем kill -9, особенно для программного обеспечения, которое записывает состояние. Если одно фоновое задание голодает пользовательский трафик, понизьте его приоритет:

sudo renice +10 -p <pid>
sudo ionice -c2 -n7 -p <pid>

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

При истощении диска удаляйте или ротируйте файлы, которые вы понимаете. Хорошими кандидатами являются старые сжатые журналы, кэши пакетов, устаревшие артефакты сборки и временные файлы от остановленных заданий. Плохими кандидатами являются файлы баз данных, активные журналы, неизвестные файлы в каталогах данных приложений и все, что вы не можете объяснить.

Заметки о первопричине для записи

После того как система стабилизируется, запишите, что изменилось. Полезные заметки конкретны:

  • Точная файловая система или ресурс, который был исчерпан.
  • Процесс, пользователь, служба, контейнер или задание cron, участвовавшее в этом.
  • Вывод команды, который это доказал.
  • Предпринятое немедленное действие.
  • Необходимое постоянное исправление.

Это не бумажная работа ради самой бумажной работы. Следующий инцидент будет намного проще, когда вы знаете, что /var заполнился, потому что журналы отладки выросли после развертывания, или что давление памяти началось, когда количество рабочих процессов удвоилось.

Лучшие практики для предотвращения

  • Регулярный мониторинг: Внедрите регулярный мониторинг ЦП, памяти и дискового пространства с помощью таких инструментов, как top, htop, free, df и специализированных решений для мониторинга (например, Nagios, Zabbix, Prometheus).
  • Автоматизируйте ротацию журналов: Убедитесь, что logrotate правильно настроен для всех служб, генерирующих журналы.
  • Настройте конфигурации приложений: Оптимизируйте настройки приложений для повышения эффективности использования ресурсов. Например, настройте рабочие процессы веб-сервера, пулы соединений с базой данных и т.д.
  • Настройте оповещения: Настройте оповещения о постоянно высоком использовании, быстром росте, убийствах OOM, заполненности файловых систем, истощении инодов и перезапусках служб. Оповещайте о трендах, а не только о жестких лимитах.
  • Обновления системы: Поддерживайте вашу систему и приложения в актуальном состоянии, так как улучшения производительности и исправления ошибок часто включаются в новые версии.
  • Ограничения ресурсов: Для многопользовательских систем или сред с контейнерами рассмотрите возможность установки ограничений ресурсов (например, с помощью ulimit или cgroups), чтобы предотвратить голодание других процессов одним процессом.

Устранение неполадок с истощением ресурсов — это в основном дисциплинированное сужение. Найдите ограниченный ресурс, определите владельца, сделайте наименьшее стабилизирующее изменение, затем исправьте причину, по которой это произошло. Базовых инструментов достаточно для большинства инцидентов, если вы используете их в таком порядке и сопротивляетесь желанию удалять или убивать, прежде чем поймете, к чему прикасаетесь.