Выберите продукт

Linux: CPU steal time в виртуализации — как измерить, найти причину и снизить влияние

CPU steal time — время, когда ваша VM готова работать, но гипервизор отдаёт CPU другим. Разберём диагностику через top/vmstat/mpstat, отличия от iowait и cgroup throttling, и план действий с данными для провайдера.
Linux: CPU steal time в виртуализации — как измерить, найти причину и снизить влияние

Если сайт «подвисает», очереди растут, а загрузка CPU выглядит странно низкой — часто виноват не ваш код и не база, а CPU steal time. Это типичная история для виртуализации: ваш Linux в виртуальной машине готов выполнять задачи, но физическое CPU-время в этот момент получает кто-то другой (соседи на хосте). В результате вы видите деградацию производительности, которая почти не лечится оптимизацией приложения, потому что узкое место выше — на уровне гипервизора.

Ниже — практическая инструкция для админов: как увидеть steal в top/vmstat/mpstat, чем он отличается от iowait, как подтвердить проблему метриками и какие действия реально помогают.

Что такое CPU steal time и почему он появляется

CPU steal (steal time, обычно метрика st) — доля времени, когда виртуальный CPU вашей VM был готов исполнять задачи, но не получил физическое CPU-время: гипервизор отдал слоты исполнения другим виртуальным машинам.

Упрощённо: «ядра» в тарифе есть, но в конкретные моменты реальная вычислительная мощность становится меньше из‑за конкуренции на хост-ноде.

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

  • Noisy neighbor: соседняя VM активно грузит CPU (бэкапы, компиляция, индексации, тяжёлые запросы и т. п.).
  • Переподписка CPU на ноде: суммарно vCPU продано больше, чем физических, и планировщик вынужден резать доступное время.
  • Хост под давлением: обслуживание, миграции, фоновые задачи платформы, неудачное размещение по NUMA.
  • Совпадение пиков: у вас и у соседей нагрузка «встретилась» в одно окно.

Steal — это не «у вас 100% CPU». Это «у вас есть работа, но CPU вам не дают». Поэтому симптомы часто выглядят как необъяснимые задержки при вроде бы умеренной загрузке.

Как steal time проявляется в реальной работе

Чаще всего steal ловят не по «процентам CPU», а по задержкам. Типовые эффекты:

  • рост времени ответа веба/API без явного роста us/sy;
  • рывки latency: то нормально, то резко хуже;
  • увеличение очередей (backlog воркеров, очередь PHP-FPM, рост времени cron);
  • таймауты в прокси/балансере из‑за внезапных пауз на бэкенде;
  • нестабильные бенчмарки: одинаковый прогон то быстрый, то заметно медленнее.

Если вы используете контейнеры, обязательно держите в голове альтернативную причину — CPU throttling из-за лимитов. У нас на Fastfox есть отдельная памятка, как быстро проверять лимиты systemd и контейнеров: лимиты CPU/памяти в systemd и их симптомы.

Вывод top и vmstat с заметным st (steal time) и ростом очереди задач

Быстрая диагностика: top, vmstat, mpstat

Начнём с базовых инструментов, которые есть почти везде. Ваша цель — увидеть st именно в то окно, когда сервис «плывёт».

1) top: ищем %st

В top steal отображается как st в строке CPU:

top

Смотрите на:

  • %st — steal time;
  • %id — idle (важно: на уровне гостя CPU может выглядеть «праздным», но задержки при этом растут);
  • load average — может расти, потому что runnable-задачи ждут слоты исполнения;
  • динамику: разовые всплески или постоянный фон.

Практическая эвристика по st:

  • 0–1% — обычно норма;
  • 2–5% — уже заметно на latency‑чувствительных сервисах;
  • 10%+ — почти наверняка будет больно;
  • 20–30%+ — сервис может «умирать» на пиках даже при нормальном коде.

2) vmstat: st по интервалам

vmstat удобен тем, что показывает картину по секундам:

vmstat 1

В конце строки есть блок CPU: us sy id wa st. Нас интересует st.

Как читать вместе с остальными полями:

  • r (run queue) растёт, us/sy не растут, но st есть — похоже на дефицит CPU из-за гипервизора.
  • wa (iowait) высокий — это уже больше про диск/сетевое хранилище, а не про steal.

3) mpstat: по всем vCPU

Для более точной картины используйте mpstat (пакет sysstat):

mpstat -P ALL 1

Это полезно, когда у вас много vCPU и steal «размазан», либо нагрузка неравномерная по ядрам.

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

Steal vs iowait vs «мне не хватает CPU»: как не перепутать

Фраза «тормозит — значит CPU» часто уводит в сторону. Важно различать три похожие по ощущениям истории.

1) Steal vs обычная высокая загрузка CPU

Если CPU действительно занят вашим кодом, обычно:

  • растут us/sy;
  • видно стабильные CPU-hungry процессы;
  • st около нуля (или незначительный).

Если же высокий steal, наблюдается «парадокс»: очереди и latency растут, а us/sy не выглядят катастрофическими — потому что гостю просто не дают исполняться.

2) Steal vs iowait

iowait (wa) — ожидание завершения ввода‑вывода: медленный диск, перегруженное хранилище, очередь fsync у базы, storage throttling.

Признаки iowait:

  • wa высокое, st низкое;
  • много процессов в D-state;
  • есть корреляция с дисковыми метриками/запросами к БД.

Признаки steal:

  • st заметно растёт при просадке скорости;
  • очереди растут без явной «дисковой» картины;
  • время выполнения CPU‑bound операций скачет.

3) Steal vs CPU throttling в контейнерах

CPU throttling из-за лимитов (cgroup quota) может давать очень похожие симптомы: воркеры «не успевают», p95/p99 растут, но st при этом может быть низким. Если у вас Docker/Kubernetes или сервисы под systemd с ограничениями — сначала проверьте лимиты и факты троттлинга (ссылка выше на разбор systemd‑лимитов поможет).

Мини-лаборатория: как подтвердить влияние steal на производительность

Чтобы перестать гадать, полезно сделать две вещи: (1) зафиксировать steal в момент деградации, (2) проверить, как ведут себя простые CPU-bound операции.

Снимок метрик по времени (5–10 минут)

Запустите параллельно (в отдельные окна/сессии):

vmstat 1
mpstat -P ALL 1

Если установлен sysstat, добавьте:

pidstat -u 1

Идея: увидеть, что процессы не выглядят «на 100% CPU» по us/sy, но сервис тормозит, а st скачет.

Простейший CPU-bound тест (аккуратно)

На проде бенчмарки делайте осторожно. Но лёгкая проверка иногда помогает: запустите кратковременную CPU‑bound команду и сравните время выполнения в разные периоды.

/usr/bin/time -p bash -c 'i=0; while [ $i -lt 20000000 ]; do i=$((i+1)); done'

Запустите 3–5 раз в «нормальное» время и 3–5 раз в момент лагов, параллельно глядя на st в vmstat. Если время выполнения гуляет в разы и это совпадает со steal — у вас сильный аргумент.

Не делайте агрессивные стресс‑тесты на рабочей базе/вебе. Наша цель — наблюдение и корреляция, а не «уложить» сервер.

Рабочее место администратора: заметки по vmstat/mpstat/pidstat и график задержек для корреляции со steal

Что делать, если steal высокий: пошаговый план

Дальше — практические действия. Важно разделить: что вы можете исправить внутри VM, а что требует вмешательства провайдера/платформы.

Шаг 1. Убедитесь, что это именно steal, а не ваша нагрузка

  • Соберите 10–15 минут vmstat/mpstat в момент проблемы.
  • Проверьте, нет ли пиков us/sy от ваших задач (cron, бэкапы, ротации, индексации).
  • Если пики совпадают с вашим cron — возможно, вы сами создаёте нагрузку, и это не noisy neighbor.

Шаг 2. Снизьте «взрывную» конкурентность у себя

Даже если первопричина — переподписка CPU, вы можете уменьшить ущерб от steal, сгладив пики:

  • Ограничьте параллелизм воркеров/обработчиков, чтобы не создавать «шквал» runnable задач.
  • Разнесите cron: тяжёлые задания не должны стартовать в одну минуту.
  • Переоцените лимиты на уровне приложений: иногда меньше потоков = меньше контеншен = ниже p99.

Идея простая: когда CPU «урезают», лучше иметь управляемую очередь, чем 200 одновременно конкурирующих процессов.

Шаг 3. Проверьте, не усугубляет ли ситуацию троттлинг по cgroup

Если вы в контейнерах, убедитесь, что проблема не в CPU quota. В этом сценарии «лечится» настройкой limits/requests и профилированием приложения, а не переносом VM.

Шаг 4. Соберите данные для обращения в поддержку

Если вы уверены, что это steal/oversubscription, подготовьте факты:

  • временной интервал проблемы (с точностью до минут) и часовой пояс;
  • вывод vmstat 1 и mpstat -P ALL 1 (несколько десятков строк) в момент деградации;
  • симптомы на сервисе: таймауты, рост p95/p99, рост очередей воркеров;
  • подтверждение, что ваши cron/бэкапы/ротации не создавали аномальных CPU‑пиков в это время.

Так провайдеру проще сопоставить вашу жалобу с телеметрией хоста и историей загрузки ноды.

Шаг 5. Тактические и стратегические решения

Если steal — редкий всплеск, иногда достаточно пережить окно или перенести тяжёлые задачи. Но если steal — постоянный фон, это системная проблема размещения.

  • Миграция на другую ноду (переезд VM на менее загруженный хост).
  • Тариф с более предсказуемыми ресурсами (меньше переподписка, выше гарантии).
  • Увеличение числа vCPU иногда помогает, но не всегда: если на ноде жёсткий дефицит CPU, steal может сохраниться.
  • Разделение ролей: вынесите БД/очереди/критичный API на отдельную VM, чтобы деградация не «роняла» всё сразу.
Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Частые вопросы и грабли

Почему load average растёт, а CPU не на 100%?

Потому что load average учитывает runnable задачи (которые хотят CPU). При steal задачи готовы работать, но им не дают слоты исполнения. В итоге очередь растёт, а us/sy может выглядеть умеренно.

Может ли steal быть из-за «плохого» приложения?

Косвенно — да: если сервис делает резкие пики CPU и конкурирует сам с собой, а затем попадает в период нехватки CPU на хосте, эффект будет сильнее. Но сам steal — это характеристика планирования CPU на уровне гипервизора.

Какие сервисы наиболее чувствительны к steal?

  • веб/API с требованиями к p99 latency;
  • базы данных и кеши под нагрузкой;
  • очереди задач, где важен предсказуемый runtime воркера;
  • SSL-терминация и шифрование при высоком RPS;
  • любые CPU‑bound задачи (рендер, конвертация, аналитика).

Короткий чеклист: steal time за 5 минут

  1. Смотрите %st в top.
  2. Запустите vmstat 1 и подтвердите рост st во время лагов.
  3. Проверьте mpstat -P ALL 1, чтобы увидеть картину по ядрам и по интервалам.
  4. Отделите steal от wa (iowait) и от CPU throttling в контейнерах.
  5. Соберите лог‑вывод и временные метки для обращения в поддержку/миграции.

Итог простой: CPU steal — один из самых неприятных и при этом хорошо диагностируемых источников нестабильной производительности в виртуализации. Чем быстрее вы научитесь замечать st и связывать его со всплесками задержек, тем меньше времени уйдёт на «оптимизацию не того места».

Если вы выбираете площадку под проекты, где важна предсказуемость latency, разумно закладывать запас по CPU и не гнаться за «максимум vCPU за минимум денег». В качестве ориентира можно начать с подбора тарифа под профиль нагрузки: как выбрать VDS по CPU и RAM под реальные задачи.

Для проектов, которым нужен отдельный контур и контроль над ресурсами, часто удобнее сразу брать VDS с подходящей конфигурацией и мониторингом, чтобы ловить steal и другие аномалии по графикам, а не по жалобам пользователей.

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

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

Debian/Ubuntu: конфликт systemd-resolved DNSStubListener на 127.0.0.53 с dnsmasq, Unbound и BIND OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: конфликт systemd-resolved DNSStubListener на 127.0.0.53 с dnsmasq, Unbound и BIND

Если локальный DNS в Debian или Ubuntu не стартует с ошибкой address already in use, причина часто в systemd-resolved и DNSStubLis ...
Debian/Ubuntu: как исправить NFS mount.nfs: access denied by server while mounting OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить NFS mount.nfs: access denied by server while mounting

Ошибка mount.nfs: access denied by server while mounting в Debian и Ubuntu обычно указывает на проблему на стороне NFS-сервера: не ...
Debian/Ubuntu: как устранить конфликт systemd-resolved DNSStubListener с BIND9, dnsmasq и AdGuard Home OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как устранить конфликт systemd-resolved DNSStubListener с BIND9, dnsmasq и AdGuard Home

Если в Debian или Ubuntu DNS-сервер не стартует из-за ошибки port 53 busy, часто причина в systemd-resolved с локальным слушателем ...