В первой части мы разобрали как работать с sysdig
. А сегодня мы максимально подробно разберем такой базовый инструмент диагностики как top/htop
. Несмотря на то, что это базовый инструмент и не такой интересный как тот же sysdig, мы не можем обойти его стороной. По ходу мы приправим всё теорией и разберем практический пример анализа вывода.
Про память в Linux
Когда вы смотрите на показатели памяти (например, в top
, free
или через cat /proc/meminfo
), важно понимать, что именно подразумевается под «used», «free», «buff/cache» и т. д. На первый взгляд может казаться, что система «съедает» всю память, но зачастую это лишь особенности кэширования и работы ядра.
Total
— Общий объём оперативной памяти (RAM), который распознаёт ядро Linux.Used
— Количество памяти, занимаемой процессами вместе буферами и кэшами.Free
— Память, которая прямо сейчас не задействована ни под процессы, ни под кэш.Buff/Cache
—Buffers
— память, зарезервированная под буферизацию операций ввода-вывода (I/O). Пример: при копировании большого файла cp bigfile /backup/bigfile часть данных попадает в буферы, прежде чем окончательно записаться на диск. Это помогает оптимизировать операции записи. По окончании записи ядро освобождает или переиспользует буферы.Cache
— память, используемая для кэширования файловых данных. Пример: когда вы повторно открываете один и тот же лог-файл, чтение во второй раз будет быстрее, так как ядро может брать данные из кэша (без повторных обращений к диску). Если приложению понадобится память, ядро автоматически «отдаст» часть кэша, так что buff/cache не означает «пропавшую» память.Available
— Показывает объём памяти, который ядро может отдать под новые процессы без использования swap. При необходимости кэш и буфер освобождаются автоматически.Swap
— Когда системе не хватает физической памяти (или при определённой настройке swappiness), неиспользуемые страницы памяти могут выгружаться в swap-раздел (или файл). Если swap активно используется, это может указывать на нехватку RAM, но иногда ядро использует swap и при наличии свободной памяти, если считает, что выгрузка «простаивающих» страниц — более эффективный вариант.
Вы можете сами, основываясь на выводе top на скриншоте, попробовать сделать выводы. И далее раскрыть расшифровку и свериться.
Разбор вывода top по памяти
Разберем на примере из скриншота базовые данные по памяти. Total: ~30.6 ГБ. Free: ~0.85 ГБ, однако buff/cache = ~8.9 ГБ и avail Mem = ~9.4 ГБ. То есть Linux эффективно использует оставшиеся ~8–9 ГБ под кэш, и при необходимости может её освободить. Swap: практически не используется (51.3 МБ), значит нехватки ОЗУ нет.
Про CPU
В строке CPU(s) в top видим восемь основных показателей — проценты от общего времени CPU и в самом верху load average.
Прежде чем перейти к %Cpu(s)
, давайте быстро разберемся с load average
. Кто-то думает, что load average — это загрузка CPU в единицу времени, например, средняя загрузка: 0.55, 0.65, 0.71 означает, что загрузка CPU примерно составляет 55% за последнюю 1 минуту. Но это неверно.
Load average
— это среднее количество процессов, находящихся в состоянии "готовы к выполнению" (в run queue) или "ожидают" (в uninterruptible state) за последние 1, 5 и 15 минут. Эти значения позволяют понять, насколько загружен процессор и как изменяется эта нагрузка с течением времени. Если значение load average равно количеству CPU (например, 4.00 на машине с 4 ядрами), это значит, что ресурсы используются оптимально. Если load average превышает количество CPU (например, 8.00 на 4 ядрах), значит, процессы ожидают своей очереди, что может указывать на перегрузку. Если load average ниже количества CPU, у процессора есть свободные ресурсы.
Теперь перейдем к %Cpu(s)
и разберем, что означает каждый параметр:
us (user)
– Время, затраченное на выполнение пользовательских процессов (приложений). Если значение us высокое, значит процессы в userspace активно нагружают процессор. Пример: сложные вычисления в Python, компрессия данных, рендеринг видео.sy (system)
– Время, занятое системными вызовами и кодом ядра (kernel space). Если sy растёт, это признак того, что ядро выполняет много работы (обработка I/O, сетевых стэков, драйверов и т. д.). Иногда это бывает из-за большого числа контекстных переключений, или интенсивного чтения-записи на диск.ni (nice)
– Время, отведённое процессам с изменённым приоритетом (nice). Если процессы запускаются с nice (пониженным приоритетом) или renice, их CPU-время может отражаться в ni. Редко встречается в большом объёме, если специально не конфигурируете приоритеты.id (idle)
– Процент времени, когда CPU простаивает. Если id высок, значит процессор почти без нагрузки. Важно понимать, что часть «простоя» может относиться к iowait, который выделяют отдельно. В prometheus иногда бывает полезно настроить себе какой то алерт на "простой" CPU, чтобы понять где можно оптимизировать (100 - (rate(node_cpu_seconds_total{mode="idle"}[30m]) * 100) < 20) * on(instance) group_left (nodename) node_uname_info{nodename=~".+"}wa (iowait)
– Время, когда CPU простаивает в ожидании операций ввода-вывода (диск, сеть, и т. д.). Если wa велик (например, >10–15%), обычно это говорит, что система не успевает обрабатывать I/O, и процессор «ждёт» данные, вместо вычисления. При высоком iowait стоит проверить диски (iotop, iostat), подсистему хранения (SSD vs HDD) и сетевые операции (если хранилище находится в сети). Как это диагностировать мы поговорим в следующих статьях данного цикла.hi (hardware interrupt)
– Время обработки аппаратных прерываний. Например, при поступлении сигнала от сетевой карты или дискового контроллера. Если hi внезапно скачет, есть риск «шторма» прерываний из-за нештатной работы железа.si (software interrupt)
– Время обработки программных прерываний (softirqs). Часто связано с сетевыми пакетами, таймерами, межпроцессным взаимодействием. Высокие значения бывают при интенсивном сетевом трафике.st (steal)
– Украденное время при работе на виртуальной машине. Гипервизор может забирать часть CPU для других виртуалок. Если st высок, значит ваша VM не получает достаточно CPU-ресурсов от хост-сервера.
Как и в случае с памятью, я предлагаю самостоятельно разобраться и сделать выводы.
Разбор вывода top по CPU
Load average: 6.17, 5.91, 5.64. Загрузка за последние 1, 5 и 15 минут. Если на машине, к примеру, 8 ядер, эти значения — не критический показатель. Полезно помнить, что Load Average включает как процессы, использующие CPU, так и те, что ждут ввода-вывода (IO wait).
us = 7.6% — пользовательские процессы не особо перегружены.
sy = 5.7% — умеренная нагрузка на ядро.
id = 55.1% — более половины времени CPU простаивает.
wa = 26.3% — довольно высокое ожидание I/O. Это может указывать на интенсивную запись/чтение. В данном случае скорее всего Redis сбрасывает свои данные. Мы пока исходим из того, что точно пока этого не знаем. Но по ходу цикла статей будем это раскрывать
si = 5.2% — есть некоторая нагрузка софт-прерываний.
st = 0.0% — на данном экземпляре нет «украденного» времени
Таблица процессов
Ниже разберём, что означают поля PR, NI, VIRT, RES, SHR в выводе top (или похожих утилит):
PR (Priority)
– приоритет, с которым планировщик ядра запускает процесс. В Linux приоритет обычно отображается целым числом, где более высокое число означает более низкий приоритет (несмотря на кажущуюся «логичность» наоборот). Значения PR могут меняться динамически ядром, исходя из нагрузки и «nice»-приоритета процесса.NI (Nice)
– базовый приоритет. Диапазон nice: от -20 (самый высокий приоритет) до +19 (низкий приоритет). По умолчанию процессы запускаются с nice = 0. Если запустить процесс с nice -n 10 COMMAND, то процесс получит NI = 10, то есть будет иметь более низкий приоритет при распределении CPU.VIRT (Virtual Memory)
— объём виртуального адресного пространства, зарезервированного или видимого для процесса. Большой VIRT не обязательно означает, что процесс реально занимает столько физической памяти; часть из этого может никогда не загружаться в оперативную память (RAM).RES (Resident Memory)
— резидентная (фактически используемая) память в физической оперативной памяти (RAM). Это объём памяти, действительно загруженный в ОЗУ для данного процесса. Если часть процесса или библиотеки выгружена в swap (или ещё не загружена), она не считается в RES.SHR (Shared Memory)
— объём разделяемой памяти, используемой процессом. Обычно это доля памяти, которую процесс использует вместе с другими (например, разделяемые библиотеки, общие сегменты). Если два процесса используют одну и ту же библиотеку, её часть может отображаться в SHR у обоих, но в действительности она хранится в памяти единоразово.-
S (Process State)
— показывает состояние процесса.R (running)
– Процесс выполняется (активно работает).S (sleeping)
– Процесс спит (ожидает события, например ввода/вывода).D (disk sleep)
– Процесс находится в непрерываемом сне (обычно связан с операциями ввода/вывода на диск).T (stopped)
– Процесс остановлен пользователем (сигналSIGSTOP
) или для отладки.t (tracing stop)
– Процесс остановлен для трассировки (например, отладчиком).X (dead)
– Процесс мёртв (в процессе завершения, больше не существует в системе).Z (zombie)
– это процесс, который завершился, но его запись в таблице процессов всё ещё существует.P (parked)
– Процесс припаркован (неактивен, но готов к работе, обычно связано с энергосбережением).I (idle)
– Процесс находится в режиме ожидания (не активно потребляет ресурсы).
Резюмируем вышесказанное - PR и NI определяют, с каким приоритетом планировщик будет выделять CPU для процесса. VIRT говорит, сколько адресного пространства потенциально доступно процессу. RES показывает, сколько физической памяти реально выделено ему в данный момент. SHR указывает, какую часть этой резидентной памяти (RES) процесс делит с другими.
Ну и уже по доброй традиции попробуйте сами проанализировать вывод top из примера. Условимся, что смотреть будем только данные по redis
.
Разбор вывода top по процессам redis
VIRT ~8.1 ГБ Это виртуальное адресное пространство (не значит, что все 8 ГБ реально заняты). В данном случае для Redis нормально поднимать большие VIRT, особенно если включены RDB/AOF-снапшоты.
- RES (фактическая резидентная память): мы видим 3.2G, 1.1G, 3.8G и т. д. У нескольких процессов Redis довольно большие значения. Суммарно они занимают значительную часть из 30 ГБ ОЗУ.
- %CPU по Redis варьируется от 9.3% до ~36%. Выглядит не очень хорош, но поскольку система многопроцессорная, это ещё не обязательно «упор» в один CPU.
Основные выводы из практического примера
Высокий iowait (26.3% wa). Процессор «ждёт» операций ввода-вывода, что может указывать на интенсивные записи/чтения (например, Redis, сбрасывающий данные на диск). Для дальнейшей диагностики можно использовать утилиты вроде iotop, iostat, dstat, чтобы выявить «виновника» I/O. О них мы поговорим в следующих сериях.
Память (buff/cache). ~8.9 ГБ в кэше и буферах — это нормально: ядро старается использовать RAM по максимуму, чтобы ускорять операции. При необходимости эта память освобождается, так что free может быть небольшим, но available (9.4 ГБ) ещё даёт большой запас.
Нагрузка на CPU (us, sy, si). Суммарный пользовательский и системный процент невысок (около 13%), однако iowait делает общую картину менее радужной. Нужно следить за si (softirq), если оно продолжит расти, возможно, идёт большой сетевой трафик или нуждаются в настройке сетевые стеки.
Load average ~6. На сервере с 8 ядрами это не критично, но при дальнейших пиках нагрузка может дойти до очередей на выполнение задач. Необходимо мониторить в динамике - нет ли дальнейшего роста или все под контролем.
Что ещё есть в top
Надо сказать, что вы можете настраивать список столбцов и отображать много других метрик (можно нажать F и выбрать интересующую метрику).
А на этом все - спасибо за внимание. При желании заглядывайте в тележку https://t.me/devopsbrain.
rezdm
htop же