ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

Linux PSI: как измерять pressure CPU, памяти и диска и ловить latency spikes

Linux PSI (Pressure Stall Information) показывает, сколько времени задачи реально «ждали» CPU, память или I/O. Разберём /proc/pressure, уровни some/full, avg10/60/300 и total, ловлю коротких spikes по дельтам и применение в cgroups и systemd-oomd.
Linux PSI: как измерять pressure CPU, памяти и диска и ловить latency spikes

PSI (Pressure Stall Information) — механизм ядра Linux, который отвечает на практичный вопрос: не «сколько ресурсов занято», а «сколько времени процессы не могли продолжать полезную работу из‑за дефицита CPU, памяти или I/O».

Если вы ловили ситуацию «CPU вроде не 100%, диски не красные, а задержки в приложении прыгают», PSI помогает быстро подтвердить факт pressure и понять его тип: CPU, memory или I/O.

Дальше — разбор, как читать /proc/pressure, что означают some/full, как использовать avg10/avg60/avg300 и total, и как применять PSI в triage на уровне системы и cgroups.

Что измеряет PSI и почему это не «ещё одна метрика загрузки»

Классические метрики (load average, iowait, %util, free/available) в основном отвечают на вопрос «насколько ресурс занят». PSI отвечает на другой: «сколько времени полезная работа не выполнялась, потому что задача упёрлась в дефицит ресурса».

В терминах ядра pressure — это ситуация, когда задачи вынуждены ждать:

  • CPU: runnable-задачи ждут процессорное время (очередь на CPU).
  • Memory: задачи блокируются из‑за reclaim/компакции/ожидания освобождения памяти, иногда на фоне свопа.
  • I/O: задачи блокируются в ожидании завершения операций чтения/записи.

PSI не «угадывает первопричину». Он фиксирует симптом — stall time — а причину вы находите корреляцией с нагрузкой, лимитами cgroup, поведением диска/свопа и метриками приложения.

Где смотреть: /proc/pressure и формат данных

PSI доступен в трёх файлах:

  • /proc/pressure/cpu
  • /proc/pressure/memory
  • /proc/pressure/io

Снять текущие значения можно обычным cat:

cat /proc/pressure/cpu
cat /proc/pressure/memory
cat /proc/pressure/io

Типичный вывод:

some avg10=0.25 avg60=0.10 avg300=0.05 total=123456789
full avg10=0.00 avg60=0.00 avg300=0.00 total=0

Что важно:

  • avg10, avg60, avg300 — скользящие средние доли времени (в процентах), когда наблюдался pressure, за 10/60/300 секунд.
  • total — суммарное время давления в микросекундах с момента загрузки (монотонно растёт). Удобно считать дельты.
  • some и full — два уровня «насколько плохо».

some vs full: как читать уровни давления

some означает: хотя бы одна задача в наблюдаемой области (система целиком или конкретная cgroup) не могла прогрессировать из‑за дефицита данного ресурса.

full означает: все не-idle задачи в наблюдаемой области одновременно не могли прогрессировать из‑за этого ресурса. Это признак «тотальной пробуксовки».

Практически: some хорошо ловит частичные очереди и микроподвисания, а full — моменты, когда сервисам реально нечем заняться кроме ожидания (обычно это уже заметно пользователям).

На CPU full часто близок к нулю, а some показывает конкуренцию. Для I/O и memory full встречается чаще при сильной деградации (например, при активном свопе или «затыке» диска).

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Если вы отлаживаете PSI на контейнерах или нескольких сервисах, чаще всего упираетесь не в «железо», а в распределение ресурсов и лимиты. На практике проще всего проверять гипотезы на отдельной VDS с предсказуемыми CPU/RAM и понятными лимитами — особенно когда нужно воспроизвести spikes под нагрузкой.

Вывод /proc/pressure с полями some/full, avg10/avg60/avg300 и total

CPU pressure: когда «CPU не 100%», но очередь уже душит

CPU pressure — это время, когда runnable-задачи хотели выполняться, но ждали планировщик. В терминах практики это «цена очереди на CPU», выраженная как доля времени ожидания.

Типичные причины:

  • Пиковая нагрузка короткими burst-ами (сжатие, шаблонизация, шифрование, сборка).
  • Ограничения CPU в cgroup (контейнеры, systemd slices): по системе в целом CPU может быть не «в красном».
  • Слишком мало vCPU для количества воркеров и конкурентных сервисов.
  • Перекос по ядрам (IRQ/softirq/NUMA), когда «узкое место» не выглядит как высокий user CPU.

Быстро сопоставить PSI и картину по CPU:

cat /proc/pressure/cpu
uptime
mpstat -P ALL 1 5

Если avg10 по CPU растёт одновременно со скачками latency, а общий %CPU не обязательно упирается в 100% на всех ядрах — проверьте лимиты cgroup и распределение нагрузки по потокам. Для systemd-юнитов полезно держать под рукой разбор лимитов: лимиты CPU и памяти в systemd и cgroups.

Memory pressure: reclaim, swap и «невидимые» паузы

Memory pressure — самая «коварная» часть PSI. Память может быть «вроде есть» (особенно если смотреть только free), но система тратит время на reclaim, ожидание I/O под своп/страницы, компакцию или упирается в лимит cgroup.

Сценарии, где PSI по памяти особенно полезен:

  • Короткие latency spikes из‑за периодических волн reclaim/компакции.
  • Память ограничена cgroup-лимитом: процесс упирается в лимит и начинает «биться» об reclaim.
  • Своп включён и диск не успевает: внешне это похоже на I/O проблему, но корень — в нехватке RAM.
  • Непредсказуемые паузы у JVM/Node/PHP-FPM при росте RSS и конкуренции за память.

Минимальный набор команд для триажа рядом с PSI:

cat /proc/pressure/memory
free -m
vmstat 1 5
grep -E 'pgscan|pgsteal|pswp' /proc/vmstat | head

Почему «vmstat vs psi» — не замена, а разные углы

vmstat показывает события и скорости (сканирование страниц, своп, runnable/blocked). PSI показывает влияние на выполнение: сколько времени задачи реально простаивали в ожидании.

Практический подход: vmstat объясняет механизм (reclaim? swap?), а PSI помогает измерить, насколько это бьёт по задержкам и SLO.

I/O pressure: ожидание диска и «неожиданные» очереди

io pressure фиксирует время, когда задачи блокировались на I/O. Это напрямую коррелирует с ситуациями, когда приложение «висит», хотя CPU свободен.

Частые причины:

  • Пиковые fsync/fdatasync и flush (БД, журналы, интенсивная запись логов).
  • Промахи по page cache и неудачные паттерны чтения (много случайного чтения, маленькие блоки).
  • Конкуренция нескольких сервисов за один диск/том.
  • Фоновая активность: бэкапы, ротации, обновления, сканирование.

Быстрый набор для сопоставления:

cat /proc/pressure/io
iostat -xz 1 5
pidstat -d 1 5

Если PSI по I/O растёт одновременно с увеличением await/r_await/w_await или высоким %util в iostat — вы почти наверняка нашли источник latency spikes. Для веб-нагрузки это часто ещё и «обратное давление» на апстримы/воркеры; полезная тема для связки — очереди и backpressure в upstream для nginx.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Если вы наблюдаете стабильный I/O pressure из‑за «шумных соседей» или общий сервер перегружен конкурентными задачами, иногда проще переехать на изолированный виртуальный хостинг под лёгкие проекты или на выделенные ресурсы в VDS для тяжёлых сервисов. PSI как раз помогает аргументировать такой переезд цифрами: «вот сколько времени мы реально стоим и ждём диск/память».

График latency spikes и метрик pressure для CPU, памяти и диска

Как ловить spikes: дельты total и простое логирование

Скользящие средние полезны для обзора, но кратковременные пики проще ловить по росту total. Идея: снимать значения раз в секунду и считать дельту между измерениями.

Самый простой «ручной осциллограф» для PSI (вывод в stdout):

while true; do date +%s; awk '{print FILENAME, $0}' /proc/pressure/cpu /proc/pressure/memory /proc/pressure/io; sleep 1; done

Дальше вы либо сохраняете это в лог и сопоставляете со временем инцидента, либо оборачиваете в сборщик метрик. Важно, что вы фиксируете факт: «в такую-то секунду stall time по memory/io/cpu резко вырос».

PSI и cgroups: почему проблема может быть не видна на уровне системы

На контейнерных хостах и серверах с несколькими сервисами по системе в целом PSI может выглядеть терпимо, но один конкретный сервис испытывает сильный pressure внутри своей cgroup.

В cgroup v2 PSI доступен как cpu.pressure, memory.pressure, io.pressure внутри директории cgroup. В systemd дерево обычно живёт в /sys/fs/cgroup по слайсам/юнитам.

Пример: узнать cgroup для сервиса (подставьте имя):

systemctl show -p ControlGroup php-fpm.service

И затем читать PSI прямо там:

cat /sys/fs/cgroup/system.slice/php-fpm.service/cpu.pressure
cat /sys/fs/cgroup/system.slice/php-fpm.service/memory.pressure
cat /sys/fs/cgroup/system.slice/php-fpm.service/io.pressure

Так вы отделяете «системе в целом нормально» от «конкретному сервису плохо» — это особенно полезно, когда SLA завязан на одном приложении.

systemd-oomd и PSI: как OOM становится предсказуемее

systemd-oomd может завершать процессы/юниты заранее, ориентируясь на pressure по памяти (и/или swap), чтобы избежать сценария «ядро внезапно убило самый дорогой процесс». Ключевой момент: он смотрит не только на «сколько памяти осталось», а на симптом — memory pressure.

Практический смысл:

  • Если у вас бывают OOM или «подвисания» при нехватке RAM, PSI помогает увидеть нарастание pressure до аварии.
  • Можно разделить сервисы по слайсам и задать политику так, чтобы при кризисе «падало менее важное».

systemd-oomd не заменяет тюнинг памяти. Если система постоянно живёт в memory pressure, вы получите либо регулярные убийства, либо деградацию. PSI полезен, чтобы доказать проблему цифрами и выбрать направление: добавить RAM, изменить лимиты, пересмотреть swap, оптимизировать потребление памяти или I/O.

Пороговые значения: что считать «плохо»

У PSI нет универсальных «красных линий» — всё зависит от нагрузки и требований по задержкам. Но удобно мыслить так:

  • avg10 — «прямо сейчас», хорошо ловит всплески.
  • avg60 — устойчивая проблема на масштабе минуты.
  • avg300 — хроническое давление.

Для latency-чувствительных веб-сервисов даже единицы процентов по memory/io pressure могут отражаться в p95/p99. Для batch/ETL это часто нормально. Правильный путь — коррелировать PSI с метриками приложения (latency, очереди, ошибки) и закрепить пороги под ваш SLO.

Типовые паттерны: как по PSI отличить вероятную первопричину

1) Растёт io pressure, потом растёт memory pressure

Часто означает, что page cache не успевает: диск медленный или перегружен, reclaim становится болезненным. В приложении это выглядит как ступенчатые задержки: то нормально, то «всё стало вязким».

2) Растёт memory pressure, затем io pressure

Часто это активный своп: сначала системе не хватает RAM, затем начинается интенсивный swap in/out, и диску становится плохо тоже. В этот момент особенно полезно смотреть vmstat (si/so) и iostat.

3) Растёт cpu pressure без роста io/memory pressure

Это конкурентная CPU-нагрузка или лимиты CPU. Для подтверждения обычно хватает mpstat, pidstat -u и проверки cgroup-лимитов.

4) PSI «в норме», но задержки есть

PSI измеряет stalls только по CPU/memory/io. Если задержки из‑за сети, блокировок в приложении (lock contention), пауз GC, DNS, или внешних зависимостей — PSI может быть чистым. И это тоже результат: вы быстрее снимаете подозрение с базовых ресурсов.

Мини-чеклист: как внедрить PSI в повседневный triage

  1. Соберите «карту нормы»: какие avg10/60/300 бывают в спокойном режиме и под типичной нагрузкой.

  2. При инцидентах фиксируйте PSI рядом с метриками приложения (latency, RPS, очереди, ошибки).

  3. Если есть контейнеры/systemd — смотрите PSI в cgroup проблемного сервиса, а не только по системе.

  4. Отдельно контролируйте memory pressure, если включён своп или есть риск OOM.

  5. Для I/O всегда добавляйте корреляцию с iostat -xz и per-process I/O через pidstat -d.

Итоги

Linux PSI — практичный способ измерять не «занятость», а реальную цену дефицита ресурсов во времени: stall time. Метрики из /proc/pressure помогают быстро понять, что именно вызывает latency spikes — cpu pressure, memory pressure или io pressure — и не тратить часы на гадания по косвенным признакам.

Если один раз встроить PSI в стандартный triage (хотя бы руками через /proc/pressure и пару утилит), особенно заметно выигрываете на «плавающих» проблемах: коротких подвисаниях, деградации под пиком и ситуациях, где традиционные графики выглядят «почти нормально».

Поделиться статьей

Вам будет интересно

memfd_create и «пропавшая» память: почему du не сходится с df и как найти deleted files через /proc, lsof и smaps OpenAI Статья написана AI (GPT 5)

memfd_create и «пропавшая» память: почему du не сходится с df и как найти deleted files через /proc, lsof и smaps

Если df показывает занятое место, а du «не видит» файлы, или RAM уходит без ясных причин, часто виноваты deleted files или shmem/m ...
Kubernetes: Pod завис в ContainerCreating — диагностика CNI, FailedMount и переполнения image filesystem OpenAI Статья написана AI (GPT 5)

Kubernetes: Pod завис в ContainerCreating — диагностика CNI, FailedMount и переполнения image filesystem

Pod может долго висеть в ContainerCreating из‑за сетевого плагина (CNI not initialized), проблем со storage (FailedMount, attach t ...
Linux: что делать, если /var/log разросся и диск переполнен OpenAI Статья написана AI (GPT 5)

Linux: что делать, если /var/log разросся и диск переполнен

Если диск «внезапно» заполнился, часто виноват /var/log: разросшийся journal, сломанная ротация, дублирование логов или удалённые, ...