С чего начать Первые шаги трек · 15 ступеней
Linux Labs

Load average: сколько задач ждёт процессор и диск

11 мин Ubuntu 24.04 · Linux 6.8 · procps 4.0

Среднее число задач, которые работают или ждут процессор (R) и ждут ядро (D), за 1, 5 и 15 минут.

Шпаргалка

8 команд Версия для печати
  • uptime load за 1, 5 и 15 минут
  • nproc число процессоров для сравнения
  • cat /proc/loadavg те же числа + задачи в R / всего
  • top load и строка %Cpu(s)
  • vmstat 1 5 r — ждут CPU, b — ждут диск
  • ps -eo stat,pid,pcpu,comm --sort=-pcpu | head кто ест CPU
  • ps -eo stat,pid,wchan:30,cmd | awk '$1 ~ /^D/' кто в D
  • cat /proc/pressure/cpu доля времени ожидания CPU

Обзор

Load average — среднее число задач, которые хотят работать: выполняются или ждут свободный процессор (состояние R) и ждут, пока ядро закончит для них операцию (состояние D). uptime, top и w печатают три числа — среднее за 1, 5 и 15 минут:

text
student@ubuntu:~$ uptime
 23:38:05 up 3 min,  2 users,  load average: 2.90, 1.43, 0.57
student@ubuntu:~$ nproc
1

Load считается в задачах, процентов в нём нет. Сравнивай его с числом процессоров из nproc. На одном процессоре 1.00 значит «занят всё время, очереди нет», а 2.90 — в среднем почти три задачи хотели работать разом. На восьми процессорах те же 2.90 — свободная машина.

Три числа

Это скользящие средние: 1-минутное быстро откликается на перемены, 15-минутное сглаживает их. По трём числам видно направление: 2.90, 1.43, 0.57 — нагрузка выросла в последние минуты, 0.30, 1.50, 2.80 — спадает.

Новое значение число догоняет постепенно. Две задачи, которые занимают процессор ровно минуту, поднимут 1-минутное число примерно до 1.3, а до 2 оно дойдёт через несколько минут. Короткий всплеск на 15-минутном числе почти не виден.

Кто входит в load: R и D

Ядро каждые 5 секунд пересчитывает задачи в двух состояниях. Задача — это каждый поток: программа с восемью занятыми потоками добавит 8.

Состояние Что делает задача В load
R выполняется или стоит в очереди к процессору да
D непрерывный сон: ждёт операцию ядра — диск, файловую систему, сеть NFS да
S спит до события: ввода, пакета, таймера нет
T, Z, I остановлена, зомби, простаивающий поток ядра нет

Состояние видно в столбце STAT у ps и S у top (см. processes).

Состояние D

Процесс в непрерывном сне ждёт, пока ядро закончит операцию за него: чтение с диска, запись в файловую систему, ответ сервера NFS. Сигналы он получит только после конца ожидания — даже kill -9:

text
student@ubuntu:~$ ps -eo stat,pid,wchan:30,cmd | awk '$1 ~ /^D/'
D       2147 percpu_rwsem_wait              touch /mnt/frz/f1
D       2148 percpu_rwsem_wait              touch /mnt/frz/f2
D       2149 percpu_rwsem_wait              touch /mnt/frz/f3
student@ubuntu:~$ kill -9 2147; sleep 1; ps -o stat,pid,cmd -p 2147
STAT     PID CMD
D       2147 touch /mnt/frz/f1

Здесь файловую систему заморозили командой fsfreeze -f, и каждая запись в неё ждёт разморозки. Столбец WCHAN — функция ядра, в которой спит процесс. Процессор такие задачи не тратят, а load растёт на единицу за каждую. Разморозили (fsfreeze -u) — процесс 2147 сразу завершился: отложенный SIGKILL сработал.

Load и загрузка процессора

Load говорит, сколько задач хотят работать. Строка %Cpu(s) в top говорит, чем занят процессор. Вместе они различают две беды на машине с одним процессором:

Что видно Задачи %Cpu(s) Что происходит
load растёт к 2 две в R по 48.8 % 100.0 us, 0.0 id две задачи делят один процессор
load 2.90 три в D 0.0 us, 90.9 id, 0.0 wa задачи ждут, процессор свободен

Поля строки %Cpu(s) — доли времени процессора за последний интервал:

Поле Что значит
us код программ
sy ядро по просьбе программ: системные вызовы, ввод-вывод
ni программы с пониженным приоритетом nice
id простой
wa простой, пока кто-то ждёт ответа диска (iowait)
st steal: процессор был нужен ВМ, а гипервизор отдал его другим машинам

Приоритет процесса понижают командами nice и renice (см. приоритет nice), его доля и попадает в ni.

wa учитывает только ожидание устройства. В примере выше три процесса в D ждут разморозки файловой системы и к диску не обращаются, поэтому wa — 0.0. Когда процесс ждёт сам диск, wa растёт: при записи dd … oflag=direct на этой же машине vmstat показал wa 82. При этом wa — тоже простой: задача, которой нужен процессор, забирает это время, и wa падает к нулю, хотя диск занят так же.

Откуда берутся числа

uptime, top и системы мониторинга читают файл /proc/loadavg:

text
student@ubuntu:~$ cat /proc/loadavg
1.72 0.68 0.25 1/125 2118

Первые три поля — load average. 1/125 — сколько задач в R прямо сейчас и сколько задач всего. Последнее поле — PID последнего созданного процесса.

Давление: /proc/pressure

Load складывает ожидание процессора и ожидание ядра в одно число. Файлы /proc/pressure/cpu, io и memory (PSI, pressure stall information) разделяют их. Так выглядит cpu, когда две задачи stress-ng --cpu 2 делят один процессор:

text
student@ubuntu:~$ cat /proc/pressure/cpu
some avg10=64.78 avg60=18.21 avg300=4.14 total=12842145
full avg10=0.00 avg60=0.00 avg300=0.00 total=0

some avg10=64.78 — 64.78 % последних 10 секунд хотя бы одна задача ждала процессор; avg60 и avg300 — то же за минуту и за 5 минут. full в io и memory — доля времени, когда ждали все работающие задачи сразу. Для cpu на уровне всей машины full всегда 0.

Рецепты

3

Load выше числа процессоров: кто в очереди

text
student@ubuntu:~$ ps -eo stat,pid,ni,pcpu,comm --sort=-pcpu | head -4
STAT     PID  NI %CPU COMMAND
R        975   0 48.8 stress-ng-cpu
R        976   0 48.8 stress-ng-cpu
Ss         1   0 10.8 systemd

Две задачи R по 48.8 % делят один процессор. Дальше — дождаться, понизить приоритет (renice -n 10 -p 975, см. processes) или остановить процесс (kill).

Найти, на чём ждут процессы в D

bash
ps -eo stat,pid,wchan:30,cmd | awk '$1 ~ /^D/'  # кто в D
grep State /proc/2147/status    # State: D (disk sleep)
sudo cat /proc/2147/stack       # стек ядра, только root
text
student@ubuntu:~$ sudo cat /proc/2147/stack
[<0>] percpu_rwsem_wait+0x103/0x120
[<0>] mnt_want_write+0x9c/0xd0
[<0>] open_last_lookups+0x319/0x400
…
[<0>] __x64_sys_openat+0x55/0xa0

Стек читается снизу вверх: системный вызов openat, просьба о записи в точку монтирования (mnt_want_write), ожидание: процесс ждёт файловую систему. Если в стеке функции nfs_ или rpc_, ждёт сервер NFS; какие ФС смонтированы по сети — findmnt -t nfs,nfs4,cifs.

Следить за load в динамике

bash
vmstat 1 5                        # r и b каждую секунду
watch -n 5 cat /proc/loadavg      # load каждые 5 секунд

В vmstat столбец r — задачи в R (работают и ждут процессор), b — задачи, которые ждут диск. Столбцы целиком — в system-monitoring.

Неполадки

5

Load высокий, а процессор свободен

В top — 90.9 id, а load на одном процессоре 2.90. Значит, задачи в D. Найди их (ps … | awk '$1 ~ /^D/', рецепт выше) и посмотри, чего они ждут:

  • wa высокий, в vmstat растёт b — ждут диск: какой диск и какой процесс, покажут iostat -x и sudo pidstat -d 1 (см. pidstat-iostat);
  • wa 0, b 0 — ждут что-то кроме устройства: замороженную ФС, сервер NFS, блокировку в ядре. Стек — в /proc/<pid>/stack.

Задача, которая висит в D дольше порога kernel.hung_task_timeout_secs (120 секунд в Ubuntu), попадает в журнал ядра. Здесь порог уменьшили до 20:

text
student@ubuntu:~$ sudo journalctl -k -o cat | grep 'blocked for'
INFO: task touch:2147 blocked for more than 20 seconds.

Процесс в D не завершается от kill -9

Сигнал ждёт конца операции ядра. Убирай причину ожидания: верни диск или сервер NFS, разморозь ФС (sudo fsfreeze -u <точка>). После этого процесс сам получит отложенный сигнал. Если устройство пропало насовсем, процесс останется в D до перезагрузки.

Load 1.00 на одном процессоре — это много?

Нет очереди: процессор занят всё время, и никто не ждёт. Тормозить начинает, когда load долго держится выше nproc и в vmstat столбец r больше числа процессоров. Короткий всплеск 1-минутного числа при спокойном 15-минутном — обычная работа.

В контейнере load как у всей машины

/proc/loadavg один на всё ядро: uptime внутри контейнера показывает load хоста со всеми его контейнерами. Нагрузку одного контейнера смотри docker stats (см. docker).

Высокий st на виртуальной машине

st (steal) — процессор был нужен ВМ, а гипервизор отдал его другим машинам. Load при этом растёт: задачи стоят в очереди дольше. Внутри ВМ это не лечится — нужен свободный процессор на хосте.

Термины

2
состояние D (непрерывный сон) state D (uninterruptible sleep)
Процесс ждёт, пока ядро закончит операцию за него: ввод-вывод диска, запись в файловую систему, ответ сервера NFS. Сигналы, даже SIGKILL, подействуют только после конца ожидания. Входит в load average. Ещё встречается в: dmesg, Процессы, Мониторинг системы: с чего начать, когда сервер тормозит, kill и ещё 6
iowait (ожидание ввода-вывода)
Простой процессора, пока хотя бы один процесс ждёт ответа диска: wa в top и vmstat, %iowait в iostat и mpstat. Это вид простоя: если процессору есть другая работа, wa падает до нуля, хотя диск по-прежнему занят. Ещё встречается в: Мониторинг системы: с чего начать, когда сервер тормозит

См. также

  • uptime-who — uptime, w и кто вошёл в систему.
  • top — load, строка %Cpu(s) и процессы в одном окне.
  • processes — состояния, сигналы и приоритет nice.
  • system-monitoring — порядок разбора «сервер тормозит».
  • kill — сигналы, которые процесс в D получит позже.
  • docker — лимиты CPU и памяти контейнера.
  • stress-ng — нагрузка на процессор для опытов с load.
Загрузка…