SSD Nodes Learn 🎉 VPS от $4.99/мес
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-08

Что такое CPU steal time на VPS и как его проверить

Узнайте, как интерпретировать столбец st в утилите vmstat. Разберитесь, как отличить реальную нагрузку на ваш сервер от нехватки ресурсов из-за соседей по физическому хосту.

Что на самом деле измеряет CPU steal time

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

Эта разница — единственная причина существования данного счётчика. Время, которое ваши процессы проводят на процессоре, отображается как us (user) или sy (system). Время, которое задача проводит в ожидании завершения операций с диском, отображается как wa (I/O wait). vCPU (виртуальный процессор), который готов к работе, находится в очереди выполнения, не имеет ожидающих операций ввода-вывода, но при этом не исполняет код, отображается как st. Ничто внутри вашего сервера не может изменить это состояние, так как решение о планировании принимается на уровень ниже — на хосте.

Это прямое следствие того, как VPS делит одну физическую машину между множеством гостевых систем. Обычная причина — «сосед»: другой гостевой сервер на том же узле потребляет много ресурсов, поэтому хост распределяет ядра между вами. Существует и вторая причина, которую часто упускают из виду. Многие провайдеры ограничивают производительность общего vCPU долей физического ядра, и на ряде гипервизоров это принудительное ограничение учитывается внутри гостевой системы как steal. Таким образом, высокое значение st говорит вам о том, что ядро не было предоставлено вам. Оно не всегда говорит о том, кто именно его занял.

Откуда берется показатель steal

Ваше ядро не может самостоятельно измерить steal, так как оно не «видит» хост. Эту информацию предоставляет гипервизор. В KVM хост записывает счетчик для каждого vCPU на страницу, общую с гостевой системой, а гостевая система суммирует его, если ядро собрано с параметром CONFIG_PARAVIRT_TIME_ACCOUNTING (это стандарт для ядер всех дистрибутивов). Xen сообщает те же данные через область runstate. Итоговое значение попадает в пространство пользователя только из одного источника:

head -1 /proc/stat

Эта строка cpu содержит десять счетчиков в тиках USER_HZ с момента загрузки в следующем порядке: user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice. Steal — это восьмое значение после метки. Все инструменты, перечисленные ниже, vmstat, top, mpstat, а также любой Prometheus exporter, считывают это поле и преобразуют два замера в процентное соотношение.

Одно следствие важнее остальных. Если гипервизор не экспортирует этот счетчик, поле навсегда останется нулевым, и все инструменты будут показывать спокойное 0.0, даже если хост перегружен. KVM и Xen экспортируют его. Гостевые системы на VMware и Hyper-V обычно показывают ноль. Проверьте платформу, прежде чем доверять нулевому значению:

systemd-detect-virt

Команда выводит имя платформы, например kvm, xen, vmware или microsoft, а на «железе» (bare metal) — none. Внутри контейнера она сообщает среду выполнения, например lxc, docker или podman, что дает информацию о контейнере, а не о физической машине под ним. На kvm ноль — это реальное доказательство того, что хост работает корректно. На платформе, которая не заполняет это поле, ноль не является доказательством, и о наличии конкуренции за ресурсы приходится судить по времени выполнения реальных задач.

Как проверить CPU steal time на VPS?

vmstat входит в состав пакета procps. Он присутствует почти в каждом образе Ubuntu и Debian для VPS, но отсутствует в некоторых минимальных образах контейнеров, поэтому установите его, прежде чем использовать.

sudo apt-get update
sudo apt-get install -y procps
vmstat --version
vmstat 1 5

vmstat --version выводит строку вида vmstat from procps-ng 4.0.4. Если вывод есть, значит утилита установлена и вы считываете реальные счетчики ядра. 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 gu
 1  0      0 3216484  98304 1284360    0    0     4    18   62  110  3  1 96  0  0  0
 2  0      0 3216232  98304 1284360    0    0     0     0  248  431  6  2 84  0  8  0

Найдите столбец st в блоке cpu справа. В текущих сборках procps-ng после него выводится столбец gu для времени KVM guest, поэтому st теперь находится на втором месте с конца, а не на последнем. Ориентируйтесь на заголовок столбца, так как его положение менялось в разных релизах.

Две привычки помогут получить достоверные данные. Первая строка данных — это среднее значение с момента загрузки, поэтому игнорируйте её и смотрите на последующие строки. Один замер не является показательным, так как steal time возникает всплесками: запустите vmstat 1 60 и наблюдайте в течение полной минуты, прежде чем делать выводы.

top сообщает то же самое число в строке сводки %Cpu(s), в поле, помеченном как st:

%Cpu(s):  6.2 us,  2.1 sy,  0.0 ni, 83.9 id,  0.0 wa,  0.0 hi,  0.3 si,  7.5 st

Для получения детализации по ядрам добавьте sysstat:

sudo apt-get install -y sysstat
mpstat -P ALL 1 5

mpstat выводит по одной строке на каждый CPU со столбцом %steal, который показывает, затронуты ли все vCPU или только один. Для истории, необходимой при обращении в техподдержку, сохраняйте результаты в файл, а не просто смотрите на экран:

date -u | tee -a ~/steal.log
mpstat -P ALL 1 5 | tee -a ~/steal.log

Запускайте эту команду через cron в те часы, когда наблюдаются проблемы, и этот файл станет весомым аргументом: вместо слов «вчера ночью было медленно» вы предоставите провайдеру точные данные за конкретные десять минут.

Что означают показатели steal?

  • Стабильно 0.0. Система исправна, либо платформа вообще не сообщает о steal. Перед тем как делать выводы, подтвердите это с помощью systemd-detect-virt.
  • Кратковременные всплески на несколько процентов. Это нормально для любого общего узла (shared node). Возможно, сосед по серверу запустил сборку или хост выполняет резервное копирование.
  • Постоянные показатели от 1 до 5 процентов на тарифе с общими ресурсами. Это ожидаемо. Низкая цена тарифа обусловлена именно использованием общих CPU.
  • Постоянные показатели от 5 до 10 процентов. Замедление, которое можно измерить. Начните фиксировать данные и сравните показатели за одни и те же часы в течение нескольких дней.
  • Более 10 процентов в течение нескольких часов. Узел переподписан (oversubscribed) для вашей рабочей нагрузки. Этот уровень оправдывает создание тикета в поддержку или переезд на другой сервер.

Рассматривайте эти диапазоны как ориентир, а не как спецификацию, поскольку ни один провайдер не дает гарантий по уровню steal на тарифах с общими ресурсами. Сопоставляйте их с тем, что именно вы запускаете. Ночное пакетное задание может пережить 15 процентов steal без каких-либо последствий. Сервис, чувствительный к задержкам, покажет их влияние на p99 задолго до того, как средние значения станут тревожными, поэтому рабочие нагрузки, чувствительные к задержкам, такие как торговые боты должны работать на выделенных ядрах.

Во сколько вам обходится steal time?

Арифметика проста. Если доля s времени процессора занята, задача, требующая фиксированного объема процессорного времени, выполняется в 1 / (1 - s) раз дольше по настенным часам. Для задачи, которой требуется 60 секунд процессорного времени:

ChartWall clock time for a job needing 60 seconds of CPU
The data behind this chart
[
  {
    "steal_percent": 0,
    "wall_clock_seconds": "60.0"
  },
  {
    "steal_percent": 3,
    "wall_clock_seconds": "61.9"
  },
  {
    "steal_percent": 8,
    "wall_clock_seconds": "65.2"
  },
  {
    "steal_percent": 15,
    "wall_clock_seconds": "70.6"
  },
  {
    "steal_percent": 25,
    "wall_clock_seconds": "80.0"
  },
  {
    "steal_percent": 40,
    "wall_clock_seconds": "100.0"
  }
]

При 3 процентах — типичное значение для общего плана (shared-plan) — эта задача выполняется 61.9 секунд вместо 60.0. Из-за этого никто не создает тикет. При 8 процентах это уже 65.2 секунд. При 40 процентах той же задаче требуется 100.0 секунд, и очередь, которая раньше успевала обрабатываться, начинает расти.

Это расчетные значения, а не результаты измерений. Модель предполагает наличие одного исполняемого потока и равномерное распределение steal в течение интервала. Реальные сервисы часто работают хуже, чем показывает кривая, так как украденный квант времени приходится на середину запроса, и задержка суммируется для всех процессов, ожидающих завершения этого запроса. Чтобы получить собственные данные, а не расчет по формуле, проведите бенчмарк VPS в спокойное время и в часы пиковой нагрузки, фиксируя st для обоих периодов.

Это steal или что-то другое?

Показатель steal легко спутать с другими симптомами. Анализируйте счетчики в совокупности, в одной строке vmstat.

  • st высокий, а r и us остаются низкими: хост не предоставляет вам ядро. Это и есть steal.
  • r значительно выше количества ваших vCPU, при этом us высокий, а st близок к нулю: вы запускаете больше задач, чем могут обработать ваши собственные CPU. Сравните r с выводом nproc. Это ваша собственная избыточная подписка, а не влияние «соседа».
  • wa высокий, а st близок к нулю: задачи заблокированы операциями ввода-вывода, что является другой проблемой и требует иного решения.
  • Load average высокий, а st и us оба низкие: показатель нагрузки также учитывает задачи в состоянии ожидания (uninterruptible), поэтому обычно это указывает на зависшее устройство или сетевой ресурс, а не на нехватку CPU.

Тарифы с возможностью кратковременного повышения производительности (burstable) заслуживают отдельного упоминания. Они предоставляют баланс кредитов, который накапливается во время простоя и расходуется при нагрузке; когда кредиты заканчиваются, провайдер ограничивает вас базовым уровнем производительности. На некоторых платформах такое ограничение отображается как steal. На других оно невидимо изнутри системы, и вы просто получаете меньше циклов процессора в секунду. Изучите описание тарифа, прежде чем делать вывод о вине «соседа».

Почему контейнер не показывает steal time

Steal — это характеристика виртуальной машины, а не контейнера, запущенного внутри неё. Docker-контейнер на вашем VPS использует общие /proc хоста, поэтому значение st, считанное внутри него, является steal самого VPS, что и требуется для мониторинга. Контейнерная виртуализация, предоставляемая как VPS, работает иначе. При использовании lxcfs значение /proc/stat внутри контейнера синтезируется на основе данных cgroup, и steal всегда равен нулю. Система мониторинга, собирающая данные только изнутри, может показывать стабильный ноль, в то время как физический сервер под ней перегружен.

Внутри контейнера аналогичный смысл имеет троттлинг по квоте CPU. В cgroup v2:

cat /sys/fs/cgroup/cpu.stat

nr_throttled подсчитывает периоды принудительного ограничения, когда группа достигла лимита CPU, а throttled_usec суммирует время, в течение которого процесс был заморожен. Рост nr_throttled означает, что ваш процесс был готов к выполнению, но не выполнялся — это то же самое ощущение, что и при steal, но вызванное установленным вами лимитом. Проверьте свои ограничения, прежде чем винить хост, особенно если вы запускаете сервисы в Docker на VPS с лимитами CPU в файле compose. Многоуровневая виртуализация добавляет еще одно место, где может теряться время, так как виртуальная машина внутри вашего VPS учитывает как steal вашего VPS, так и собственную задержку планировщика. Учитывайте это, если вы используете вложенную виртуализацию на VPS.

Что делать при постоянном steal

Никакие настройки внутри гостевой системы не исправят steal, так как планировщик, принимающий решения, работает вне гостевой ОС. Существует четыре реальных способа действий.

Сначала соберите доказательства. Зафиксируйте временные метки в UTC, длительность каждого эпизода, частоту повторений и то, показывает ли mpstat, что затронут один vCPU или все сразу. Неделя записанных данных ценнее, чем один скриншот.

Откройте тикет с этими данными. Задайте два прямых вопроса: переподписан ли (oversubscribed) этот узел в указанные промежутки времени и можно ли перенести ваш инстанс. Вставьте вывод vmstat и точное время. Провайдеры реагируют на воспроизводимые интервалы, а тикет с жалобой «сервер тормозит» получит в ответ просьбу предоставить данные. Объем работы, который вы можете переложить на поддержку, — это одно из практических различий между управляемым и неуправляемым VPS.

Запросите миграцию. Перенос гостевой системы на менее загруженный узел — стандартная процедура для провайдера, которая обычно требует лишь короткой перезагрузки. Это бесплатное решение, которое помогает в типичном случае, когда на одном узле случайно оказалось несколько «тяжелых» соседей.

Устраните конкуренцию за ресурсы покупкой. Тарифы с выделенными vCPU резервируют физические ядра за вашим инстансом, поэтому счетчик steal будет равен нулю. Это стоит дороже каждый месяц, но является честным решением для нагрузки, которая не терпит вариативности. Если этого недостаточно или вам нужна монополия на пропускную способность памяти, следующий шаг — выделенный сервер вместо VPS.

Пока вы ожидаете решения, уменьшите влияние steal. Запускайте меньше рабочих потоков, чем у вас есть vCPU, так как потоки, которые не могут получить ядро, лишь увеличивают количество переключений контекста. Перенесите пакетную обработку на часы, когда узел менее загружен (это вы уже знаете из своих логов). Затем снова проведите замеры той же командой в те же часы, чтобы иметь возможность подтвердить эффективность изменений, а не гадать.

FAQ

Какое значение CPU steal time считается нормальным для VPS?

На тарифах с разделяемыми ресурсами кратковременные всплески и стабильное значение ниже 5 процентов являются нормой, так как разделяемый CPU означает, что хост распределяет физические ядра между гостевыми системами. Стабильно высокие двузначные показатели в течение нескольких часов — это не норма, и по этому поводу стоит создать тикет. На тарифах с выделенными vCPU ожидаемое значение составляет 0.0, поэтому любое отклонение здесь является неисправностью, о которой следует сообщить. Оценивайте показатель исходя из вашей нагрузки: ночное пакетное задание может пережить steal, который недопустим для чувствительного к задержкам API.

Исправит ли переход на более дорогой тариф высокий steal time?

Сам по себе — нет. Большее количество vCPU на том же разделяемом узле означает, что больше виртуальных процессоров конкурируют за одни и те же физические ядра, и процентное значение может остаться прежним. Устранить steal можно только выделением ресурсов CPU или переездом на менее загруженный узел. Большая доля загруженной машины — это всё ещё доля загруженной машины.

Почему на моей VPS значение steal time равно 0, хотя сервер явно работает медленно?

Есть две основные причины. Гипервизор может вообще не передавать этот счётчик, что типично для платформ VMware и Hyper-V, поэтому поле остаётся нулевым независимо от действий хоста. Запустите systemd-detect-virt, чтобы узнать, на какой платформе вы работаете. В противном случае узкое место находится в другом: проверьте wa на наличие ожиданий ввода-вывода, сравните r с nproc для оценки собственной нагрузки и изучите /sys/fs/cgroup/cpu.stat внутри контейнеров на предмет ограничения квот.

Могу ли я уменьшить steal time изнутри своего сервера?

Вы не можете изменить планировщик хоста изнутри гостевой системы. Вы можете лишь уменьшить негативный эффект. Запускайте меньше рабочих потоков, чем у вас есть vCPU, чтобы меньше задач находилось в очереди на выполнение в ожидании свободного ядра. Перенесите пакетные задания на часы, когда узел менее загружен. Кэшируйте результаты, чтобы меньше запросов требовали процессорного времени. Изменения, которые действительно устраняют steal — миграция на другой узел или выделенные ядра — находятся на стороне провайдера.