Обновить

CPU steal time: как измерить, как доказать и когда он ни при чём. В логах пусто, загрузка процессора умеренная, а приложение отвечает вдвое медленнее обычного. Один из кандидатов на объяснение — steal time: время, когда виртуальная машина была готова считать, но не получила физическое ядро.

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

Как steal вообще появляется Гипервизор раздаёт физические ядра между виртуальными машинами. Когда планировщик гостевого ядра ставит задачу на vCPU, а гипервизор в этот момент отдал физическое ядро другой машине, гостевое ядро видит, что время прошло, а работа не выполнялась. Эта разница и учитывается как steal.

Отсюда важное следствие: steal измеряется изнутри гостя и всегда является косвенной оценкой. Гость не знает, почему ему не дали ядро. Причин минимум четыре:

  • конкуренция с соседними VM на ноде;

  • ограничение по CPU на уровне тарифа (квота), которое гипервизор применяет к вам;

  • накладные расходы самого планировщика гипервизора;

  • кратковременные всплески — миграция VM, резервное копирование ноды, обслуживание.

Где steal не виден вообще? Если у вас контейнерная виртуализация (lxc, openvz), steal time не появится никогда — механизма для него нет, ядро общее с хостом. Проверить:

systemd-detect-virt

Аналог steal для контейнеров — троттлинг по cgroup:

grep -E 'nr_throttled|throttled_usec' /sys/fs/cgroup/cpu.stat
cat /sys/fs/cgroup/cpu.max

Растущий nr_throttled означает, что вы выбираете свою квоту. Это не соседи и не оверселлинг — это ваш лимит, и решается он либо оптимизацией, либо тарифом.

Какие значения считать нормой. Универсальной нормы нет — она зависит от платформы виртуализации, политики провайдера и тарифа. Практические ориентиры, которые у меня обычно работают:

  • 0–1% — фон, встречается почти везде, игнорируем.

  • 3–5% — повод посмотреть динамику и сопоставить с задержками приложения. Само по себе не проблема.

  • выше 10% устойчиво — заметно влияет на латентно-чувствительные сервисы: API, realtime, базы под нагрузкой. Пакетную обработку может почти не задевать.

Ключевое слово — устойчиво. Смотрите значение за 10–15 минут, а не пиковый выброс. Разовый скачок до 30% на две секунды не значит ничего.

Как отличить соседей от собственной квоты. Единственный надёжный способ — сопоставить steal с вашей нагрузкой.

Постройте два ряда за сутки: steal и ваш собственный CPU usage (us + sy). Дальше:

  • Steal растёт вместе с вашей нагрузкой и падает вместе с ней — почти наверняка вы упираетесь в квоту тарифа. Провайдер тут ни при чём.

  • Steal приходит независимо от вашей активности, в том числе ночью при простое, — это внешняя конкуренция.

  • Steal ровным фоном 2–3% круглосуточно — накладные расходы платформы, обычно нормально.

Без исторических данных этот анализ невозможен, поэтому sysstat стоит поставить заранее, а не в момент инцидента.

Что передавать в поддержку? Обращение вида «у меня высокий steal» почти всегда возвращается с просьбой уточнить. Работает такой набор:

  • вывод sar -u 1 600 или график за несколько часов;

  • mpstat -P ALL 1 за минуту — с разбивкой по ядрам;

  • ваша собственная загрузка CPU за тот же период, чтобы показать отсутствие корреляции;

  • конкретные временные метки, когда приложение деградировало;

  • systemd-detect-virt и параметры тарифа.

Что не поможет

  • Оптимизация кода. Если ядро вам не выдают, эффективность вашего кода на steal не влияет.

  • Добавление vCPU. Иногда даже ухудшает: больше vCPU — больше конкуренции за планирование, особенно на переподписанной ноде.

  • Перезагрузка. Помогает только если приводит к переезду на другую ноду, и это лотерея.

Чек-лист

systemd-detect-virt                          # есть ли steal в принципе
vmstat 1                                     # характер: плато или выбросы
mpstat -P ALL 1                              # распределение по ядрам
sar -u 1 600                                 # устойчивость за 10 минут
grep throttled /sys/fs/cgroup/cpu.stat       # для контейн
Теги:
+15
Комментарии0
ЕЖЕДНЕВНЫЙ ХАБР | 7 АВГ 2026
Охват37K

АКПП Voith не включается выше второй передачи: разбираемся в J1939

Изучаю шину CAN J1939 через написание самописных утилит. Целенаправленно отключал датчик наддува для проверки своих программ.

И здесь случай: Идёт выпуск машин на маршрут. На одном из автобусов АКПП не включается выше второй передачи. Сканера нет читать нечем. Но есть C, Linux, CANable, map_id_j1939, viz_j1939.

АКПП Voith не включается выше второй передачи: разбираемся в J1939

Публикации