В первой части мы разобрали как работать с 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.
ссылка на оригинал статьи https://habr.com/ru/articles/876428/
Добавить комментарий