Высокий load average в Linux: что он показывает на самом деле и как найти причину
Команда KAI Lab · · 9 мин чтения
Load average в Linux — это среднее число задач, которые выполняются или ждут процессор (состояние R), плюс задач в непрерываемом ожидании, чаще всего диска (состояние D), за 1, 5 и 15 минут. Высокое значение — ещё не диагноз: сравните его с числом ядер (nproc) и посмотрите в top или vmstat, чем заняты процессоры — работой (us, sy) или ожиданием ввода-вывода (wa).
Отсюда главная ошибка новичка: увидеть load 11 и решить, что «процессор не вывозит». На сервере из примера ниже процессоры простаивают больше чем на 80%, а тормозит всё из-за диска. Разберём, как отличить одно от другого за пять минут.
Что такое load average на самом деле
Три числа в uptime и top берутся из /proc/loadavg. Документация ядра описывает их как число задач в очереди на выполнение (R) или в ожидании дискового ввода-вывода (D), усреднённое за 1, 5 и 15 минут.
Три детали, без которых цифры легко понять неправильно:
- Это не проценты и не нормировано на ядра. В
man uptimeпрямо сказано: load 1 на одноядерной машине означает, что она была занята всё время, а на четырёхъядерной — что простаивала 75% времени. - Считаются потоки, а не процессы. Java-сервис с сотней потоков, которые застряли на диске, добавит к load сотню.
- Это не среднее арифметическое. Ядро считает экспоненциально сглаженное значение. Брендан Грегг показал на опыте: если на простаивающей машине запустить один поток, который крутится в цикле, «минутный» load через минуту дойдёт только примерно до 0,62.
Почему в Linux в load попадает ожидание диска? Это решение 1993 года: Маттиас Урлихс прислал патч, потому что процессы, которые ждут медленного свопа или диска, тоже нагружают систему. Изменение вошло в Linux 0.99 patchlevel 14. С тех пор load average в Linux — нагрузка на систему целиком, а не только на процессор, и в других ОС он может считаться иначе.
Симптом → команда → что смотреть
| Симптом | Команда | Что смотреть |
|---|---|---|
| Load выше числа ядер | nproc, uptime | во сколько раз load больше числа ядер и растёт ли он: минутное значение против 15-минутного |
| Подозрение на CPU | top, клавиша P | us и sy в строке %Cpu(s), процессы с большим %CPU |
| CPU простаивает, а load высокий | vmstat 1 | r — очередь к процессору, b — ждут ввода-вывода, wa — простой в ожидании диска |
| Подозрение на диск | iostat -x 5 | %util, r_await и w_await, aqu-sz |
| Кто нагружает диск | pidstat -d 5 | процессы с большими kB_rd/s и kB_wr/s |
| Процессы «висят» | ps -eo state,pid,user,comm | строки с состоянием D |
| Виртуалка тормозит без видимой нагрузки | vmstat 1 | st — время, которое забрал гипервизор |
| Нужна точная картина ожиданий | cat /proc/pressure/io | some avg10 — доля времени, когда задачи ждали ввода-вывода |
Шаг 1. Сравните с числом ядер
$ uptime
03:14:07 up 23 days, 5:17, 1 user, load average: 11.37, 10.92, 7.85
$ nproc
4
$ cat /proc/loadavg
11.37 10.92 7.85 1/423 91544Load почти втрое выше числа ядер, и он растёт: минутное значение больше 15-минутного, значит проблема началась недавно и не прошла. Если бы было наоборот — 3, 7, 11, — нагрузка уже спадала бы.
Четвёртое поле /proc/loadavg — 1/423: прямо сейчас в состоянии «готов выполняться» одна задача из 423. При load 11 это подсказка: основную часть load дают не очередь к процессору, а задачи в D.
Шаг 2. top: работа или ожидание
$ top
top - 03:14:07 up 23 days, 5:17, 1 user, load average: 11.37, 10.92, 7.85
Tasks: 191 total, 1 running, 190 sleeping, 0 stopped, 0 zombie
%Cpu(s): 2.6 us, 2.3 sy, 0.0 ni, 12.3 id, 82.7 wa, 0.0 hi, 0.1 si, 0.0 st
MiB Mem : 7937.6 total, 402.6 free, 1568.3 used, 5966.7 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 6071.2 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
81234 backup 20 0 15432 4120 2984 D 2.3 0.1 0:41.17 rsync
90312 postgres 20 0 223440 61512 58436 D 1.0 0.8 0:12.40 postgres
412 root 20 0 0 0 0 D 0.3 0.0 3:02.51 jbd2/vda1-8
2187 app 20 0 3542116 912344 21480 S 0.7 11.2 82:14.03 javaСтрока %Cpu(s) отвечает на главный вопрос. Пользовательский код (us) и ядро (sy) вместе занимают меньше 5%. Зато wa — 82,7%: процессорам нечего делать, пока не закончится ввод-вывод. В столбце S у верхних процессов D — непрерываемое ожидание.
Если бы картина была другой — us под 90%, wa около нуля, — это настоящая нехватка процессора. Тогда в top нажмите P, чтобы отсортировать по %CPU, и разбирайтесь с верхним процессом.
Шаг 3. vmstat: очередь к процессору или к диску
$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 412304 81220 6027816 0 0 35 212 310 590 2 1 96 1 0
1 13 0 409880 81228 6029544 0 0 412 41236 2984 5710 2 2 13 83 0
0 14 0 410512 81236 6031012 0 0 388 39880 2901 5602 3 2 12 83 0
1 14 0 408992 81240 6032384 0 0 520 40412 3012 5840 3 3 11 83 0
0 13 0 407420 81252 6034120 0 0 402 39120 2890 5588 2 2 13 83 0Первая строка — средние с момента загрузки, смотрите со второй. Столбец r — задачи, которые выполняются или ждут процессор: 0–1. Столбец b — заблокированные в ожидании ввода-вывода: 13–14. Это и есть наш load. Запись на диск (bo) — около 40 МБ/с, в свопе (si, so) нули, значит память ни при чём.
Как читать vmstat быстро:
rстабильно больше числа ядер — не хватает процессора;- растёт
bиwa— упёрлись в диск или сетевое хранилище; - ненулевые
siиso— система свопится, это проблема памяти, а диск страдает как следствие; - заметный
stна виртуалке — гипервизор отдаёт ваши такты соседям. Внутри машины это не лечится: к провайдеру или на другой тип инстанса.
Шаг 4. iostat: упёрлись ли в диск
$ iostat -xy 5 1
avg-cpu: %user %nice %system %iowait %steal %idle
2.61 0.00 2.35 82.72 0.00 12.32
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
vda 12.40 196.00 0.00 0.00 12.35 15.81 806.20 40212.80 37.00 4.39 96.40 49.88 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 77.87 100.00Флаг -y пропускает отчёт со средними с момента загрузки. Что здесь важно:
w_await96 мс — столько в среднем ждёт каждая запись, включая время в очереди. Для SSD нормальные значения — единицы миллисекунд;aqu-szоколо 78 — средняя длина очереди запросов к устройству;%util100 — устройство было занято всё время.
С %util осторожно. В man iostat оговорено: для устройств, которые обслуживают запросы параллельно, — RAID и современных SSD — 100% не означает предел. Смотрите на рост await и очереди: если запросы ждут всё дольше, диск не справляется.
Шаг 5. Кто именно ждёт и кто пишет
Процессы в состоянии D:
$ ps -eo state,pid,user,comm | awk '$1 == "D"'
D 412 root jbd2/vda1-8
D 81234 backup rsync
D 90312 postgres postgres
D 90318 postgres postgresjbd2 — поток журнала ext4, он ждёт вместе со всеми. Чтобы увидеть и потоки, добавьте флаг -L. А кто создаёт нагрузку, покажет pidstat -d:
$ pidstat -d 5 1
03:15:07 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
03:15:12 0 412 0.00 302.40 0.00 0 jbd2/vda1-8
03:15:12 34 81234 0.00 33917.60 0.00 0 rsync
03:15:12 113 90312 184.80 5992.00 0.00 0 postgres
Average: UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
Average: 0 412 0.00 302.40 0.00 0 jbd2/vda1-8
Average: 34 81234 0.00 33917.60 0.00 0 rsync
Average: 113 90312 184.80 5992.00 0.00 0 postgresКартина сложилась: ночной бэкап через rsync пишет около 33 МБ/с на тот же диск, где живёт база. Облачный диск упёрся в свой лимит, запросы PostgreSQL встали в общую очередь, и приложение тормозит вместе с ними. Столбец iodelay покажет нули, пока в ядре не включён учёт задержек (kernel.task_delayacct), — это нормально.
Отдельный случай: процессы в D, а iostat показывает спокойный диск. Тогда проверьте сетевые хранилища. Если NFS-сервер перестал отвечать, в dmesg будет строка вида nfs: server 10.0.0.5 not responding, still trying, а процессы, которые туда обращаются, повиснут в D и поднимут load.
Что делать, когда причина найдена
Нагрузку создаёт фоновая задача. Перенесите её на время, когда сервис меньше нагружен, или на другой диск. Задачу, запущенную через systemd, можно ограничить по скорости записи — это работает через cgroup v2:
# /etc/systemd/system/backup.service.d/io.conf
[Service]
IOWriteBandwidthMax=/dev/vda 15M
CPUQuota=50%После правки — sudo systemctl daemon-reload. ionice -c3 тоже бывает полезен, но приоритеты ввода-вывода поддерживают только планировщики bfq и mq-deadline. Текущий виден в /sys/block/vda/queue/scheduler; с планировщиком none ionice ничего не изменит.
Процессору правда не хватает. Найдите процесс в top, выясните, нормальная ли это нагрузка. Если нормальная — масштабируйтесь или ищите медленный код. Если нет — это баг, который надо чинить, а не маскировать дополнительными ядрами.
Свопится. Load и диск здесь следствие, а причина — память. Смотрите, кто её съел, и проверяйте лимиты. Про то, как ядро убивает процессы при нехватке памяти, — в статье OOMKilled и код 137.
Диск просто заполнен. Переполненная файловая система тоже даёт странные задержки и ошибки записи; порядок диагностики — в статье закончилось место на диске.
PSI: что показывает точнее load average
С Linux 4.20 в ядре есть Pressure Stall Information — доля времени, которую задачи потеряли в ожидании процессора, памяти или ввода-вывода:
$ cat /proc/pressure/io
some avg10=78.41 avg60=74.02 avg300=51.33 total=1830447711
full avg10=61.20 avg60=58.77 avg300=40.16 total=1422118093
$ cat /proc/pressure/cpu
some avg10=1.12 avg60=0.98 avg300=0.87 total=402211934
full avg10=0.00 avg60=0.00 avg300=0.00 total=0some — доля времени, когда хотя бы одна задача ждала ресурс; full — когда ждали все активные задачи одновременно. Здесь за последние 10 секунд задачи ждали ввода-вывода 78% времени, а процессора — около 1%. Ответ тот же, что дали top, vmstat и iostat, но одной командой и уже в процентах.
Нужен ли алерт на load average
Будить человека из-за одного load average — плохая идея. Load 20 на 32 ядрах — обычный рабочий день, а load 3 на двух ядрах при зависшем NFS — авария. Алерт должен срабатывать на то, что чувствуют пользователи: задержки и ошибки. А load, wa и PSI — это то, что открывает дежурный, когда алерт уже пришёл. Как выбирать такие сигналы, — в статье SLO, SLI и бюджет ошибок.
Вопрос «что такое load average и почему он высокий при простаивающем процессоре» — классика собеседований по Linux. Ответ из этой статьи укладывается в минуту: R плюс D, сравнить с ядрами, посмотреть wa.
Во втором месяце симулятора DevOps KAI Lab есть тикет «Сервер файлов загружен на 350%»: пользователи жалуются, что фото товаров грузятся по десять секунд, и причину нужно найти по процессам на живом сервере, а не перезагрузкой. Консоль отвечает реальными выводами команд, поэтому порядок из этой статьи там можно пройти руками.
Частые вопросы
Какой load average считается нормальным? Универсального порога нет. Ориентир — число ядер из nproc: load стабильно выше этого числа говорит, что задачам приходится ждать. Но важнее, чего именно они ждут: процессора или диска.
Почему load average высокий, а процессор свободен? В Linux load учитывает задачи в состоянии D — обычно они ждут диск или сетевое хранилище. Проверьте wa в top, столбец b в vmstat и iostat -x.
Что такое iowait? Доля времени, когда процессор простаивал, а в системе был незавершённый запрос к диску. Высокий wa не значит, что процессор занят, — наоборот, он ждёт.
Показывает ли load average загрузку CPU в процентах? Нет. Это среднее число задач, а не процент. Load 4 на четырёх ядрах — полная занятость, на одном ядре — очередь из трёх задач сверх того, что процессор успевает выполнить.
Почему минутное значение не падает сразу после того, как нагрузка ушла? Load average — экспоненциально сглаженная величина, а не среднее за последнюю минуту. После всплеска значения снижаются плавно, и 15-минутное держится дольше всех.
Источники
- man7.org: proc_loadavg(5) — что лежит в
/proc/loadavg: задачи в R и D. - man7.org: uptime(1) — load не нормирован на число процессоров.
- man7.org: top(1), ps(1), vmstat(8) — состояния процессов и поля
us,sy,wa,st,r,b. - man7.org: iostat(1), pidstat(1) —
%iowait,await,aqu-sz,%util,kB_wr/s. - Brendan Gregg. Linux Load Averages: Solving the Mystery, 08.08.2017 — патч 1993 года и опыт с «минутным» средним.
- Linux kernel. PSI — Pressure Stall Information; Linux 4.20 на kernelnewbies.
- Linux kernel. Block io priorities — какие планировщики поддерживают приоритеты; Delay accounting.
- man7.org: systemd.resource-control(5) —
IOWriteBandwidthMax=,CPUQuota=.