SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-10-19

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

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

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, August 7, 2026.

Что на самом деле измеряет 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, наличие данных о steal зависит от того, что предоставляет хост и что поддерживает гостевое ядро, поэтому нулевое значение само по себе ни о чем не говорит. Проверьте платформу, прежде чем доверять нулевому показателю:

systemd-detect-virt

Команда выводит имя платформы, например kvm, xen, vmware или microsoft, а также none для физического оборудования (bare metal). Внутри контейнера команда сообщает среду выполнения, например 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 61, что даст шестьдесят односекундных выборок после строки со средним значением, и наблюдайте в течение полной минуты, прежде чем делать выводы.

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 процентов в течение нескольких часов подряд. Либо узел переподписан для вашей нагрузки, либо применяется ограничение CPU вашего тарифа, и некоторые провайдеры отображают это ограничение как steal. Это уровень, оправдывающий создание тикета в поддержку или смену провайдера.

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

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

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

ГрафикWall clock time for a job needing 60 seconds of CPU
Данные, на которых построен график
[
  {
    "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 процентах, что является обычным показателем для тарифов с разделяемыми ресурсами, задача выполняется за 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 близок к нулю: задачи заблокированы операциями ввода-вывода (I/O), что является другой проблемой и требует иного решения.
  • 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.

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

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

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

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

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

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

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

FAQ

Каков нормальный показатель CPU steal time на VPS?

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

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

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

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

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

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

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

Была ли эта статья полезной?