MAATRIX / Блог / Steal time растёт месяц за месяцем: когда виртуалка исчерпала себя окончательно

Steal time растёт месяц за месяцем: когда виртуалка исчерпала себя окончательно

MAATRIX

Полгода назад сервер летал, сейчас те же запросы иногда «подвисают» на пустом месте — при этом код не менялся, нагрузка от пользователей растёт разве что плавно, а htop внутри виртуалки не показывает ничего страшного. Одна из вероятных причин, которую стоит проверить прежде, чем переписывать код или заказывать апгрейд тарифа, — steal time, метрика украденного процессорного времени, и то, как она вела себя не сегодня, а на протяжении последних месяцев. Разовый всплеск steal time — это нормальный шум разделяемой инфраструктуры. Устойчивый рост из месяца в месяц — это уже не шум, а диагноз конкретному физическому хосту, на котором живёт ваша VPS.

Что такое steal time и почему немного — это нормально

Steal time (в top и vmstat — колонка %st или st) — это доля времени, когда вашей виртуальной машине было нужно процессорное время, а гипервизор в этот момент отдал физическое ядро другой виртуалке на том же хосте. Технически это работает так: у гипервизора есть ограниченный набор физических ядер и очередь виртуальных машин, которым нужно раздать такты по расписанию. Когда очередь до вас не доходит вовремя — это время засчитывается как «украденное». Подробный разбор механики метрики, включая то, чем она принципиально отличается от обычной загрузки CPU (us/sy), — в статье про steal time и шумного соседа, здесь не будем повторять эту часть.

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

Эпизодический steal time в несколько процентов, который то появляется, то пропадает, обычно означает ровно то, чем кажется: сосед по хосту в моменте выполнил тяжёлую, но короткую задачу, гипервизор перераспределил такты, и через несколько секунд-минут всё вернулось в норму. Это фон разделяемой инфраструктуры, а не сигнал тревоги. Отдельный вопрос — устойчивая динамика этого фона на длинной дистанции, и именно об этом статья.

Разовый скачок и растущий тренд — принципиально разные истории

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

Разовый скачок — это шум. Сосед запустил бэкап, деплой, батч-задачу — гипервизор временно перераспределил ядра, показатель поднялся на несколько минут и опустился обратно. Через день, через неделю картина такая же, как и была: где-то фон около нуля, где-то небольшие всплески в предсказуемое время суток (обычно вечерний пик). Это нормальная жизнь общего хоста, и она не требует действий, если не мешает конкретным пользователям здесь и сейчас.

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

Разница практическая: с разовым скачком ничего делать не нужно, он пройдёт сам. С растущим трендом ничего само не пройдёт — плотность хоста не имеет тенденции сама по себе снижаться, только расти дальше, пока кто-то (провайдер по вашей просьбе, либо вы сами сменой тарифа или сервера) не вмешается.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Почему это не то же самое, что нехватка ресурсов по вашему тарифу

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

Нехватка выделенных вам ресурсов тарифа — это когда ваша нагрузка выросла и вплотную подошла или уже упёрлась в лимиты, которые вы сами купили: 2 vCPU, 4 ГБ RAM и так далее. Это видно по высокой загрузке us+sy внутри top — процессор реально занят выполнением вашего кода, вашей базы, ваших запросов. Решение здесь понятное и полностью в ваших руках: оптимизировать код, добавить кеширование, либо честно апгрейднуть тариф — купить больше ядер и памяти.

Steal time — принципиально другая история. Он означает, что даже в рамках уже оплаченного тарифа вы физически не получаете обещанные вычислительные такты — не потому что вам мало купленного, а потому что гипервизор не может отдать вам даже то, что вы уже купили, потому что физическое железо в этот момент занято чужими виртуалками. Апгрейд тарифа с 2 vCPU до 4 vCPU на том же перегруженном физическом хосте эту проблему не решает и иногда даже не облегчает — вы просто покупаете больше виртуальных ядер у того же гипервизора, у которого и так не хватает физических тактов на всех арендаторов. Ключевой диагностический признак: us/sy у вас невысокие или умеренные (то есть собственной нагрузки, которая объясняла бы тормоза, нет), а лаги при этом есть и коррелируют по времени с ростом st.

На практике часто встречается смесь: нагрузка проекта действительно органически растёт (это нормально, это рост бизнеса), и одновременно растёт steal time на хосте (это не про ваш рост, а про соседей и заполненность хоста). Раздельный мониторинг обеих метрик — единственный способ не перепутать, за какую из двух проблем вы платите апгрейдом тарифа, а какую апгрейдом не решить в принципе.

Как измерять: не разовый снимок, а лог с историей

Отличить тренд от шума на глаз, по редким ручным проверкам top, почти невозможно — память о том, «как было полгода назад», не годится в качестве данных. Нужен систематический лог с метками времени.

Базовая идея на Linux — снимать значение st из vmstat или top через равные промежутки и складывать в файл вместе с датой:

#!/usr/bin/env bash
# /usr/local/bin/steal-log.sh — снимок steal time раз в запуск
ST=$(vmstat 1 2 | tail -1 | awk '{print $17}')
echo "$(date '+%Y-%m-%d %H:%M') st=${ST}" >> /var/log/steal-history.log
# crontab -e — несколько снимков в сутки, чтобы усреднение по дню было честным
0 3,9,13,18,22 * * * /usr/local/bin/steal-log.sh

Расположение колонки st в выводе vmstat 1 2 может отличаться по номеру поля в зависимости от дистрибутива и версии procps — перед тем как класть скрипт в крон, стоит один раз вручную свериться, какая колонка у вас действительно последняя в блоке cpu, и подставить правильный номер в awk.

Если на сервере уже установлен sysstat, sar даёт более надёжный источник истории без самодельного скрипта — он и так постоянно собирает системную статистику, включая %steal, и хранит её по дням:

apt install sysstat -y
# посмотреть накопленную статистику CPU за сегодня
sar -u
# статистика за конкретный прошедший день (файлы хранятся в /var/log/sysstat/ или /var/log/sa/)
sar -u -f /var/log/sysstat/sa15

Глубина хранения истории в sysstat по умолчанию обычно ограничена несколькими неделями — для наблюдения за трендом на дистанции нескольких месяцев самодельный лог в отдельный файл (как в примере выше) надёжнее, потому что вы сами контролируете, сколько хранить и как ротировать.

Если у вас уже есть система мониторинга (Zabbix, Grafana с node_exporter или аналог) — правильнее завести st туда как обычную метрику наравне с CPU/RAM/диском, а не городить отдельный лог-файл. Тогда тренд виден сразу на графике за произвольный период, без ручного разбора текстовых логов.

Как читать накопленную историю и отличать тренд от шума

Сырой лог с отметками времени сам по себе не даёт ответа — нужно свести его к сравнимым цифрам за периоды.

Считайте среднее по неделям или месяцам, а не смотрите на отдельные строки. Один плохой день ничего не значит — сосед мог неделю гонять тяжёлую задачу и остановиться. Значение имеет динамика усреднённого показателя от периода к периоду.

Простой способ получить помесячное среднее прямо из лога в формате выше:

awk '{split($1,d,"-"); m=d[1]"-"d[2]; split($3,s,"="); sum[m]+=s[2]; cnt[m]++}
     END {for (m in sum) printf "%s: avg_st=%.2f%% (n=%d)\n", m, sum[m]/cnt[m], cnt[m]}' \
     /var/log/steal-history.log | sort

Результат — по одной строке на месяц со средним значением st и числом замеров. Если цифра растёт от месяца к месяцу без видимых откатов назад — это и есть искомый тренд.

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

Не гонитесь за абсолютным порогом. Универсального числа, начиная с которого steal time «плохой», не существует — слишком многое зависит от чувствительности вашего приложения к задержкам и от того, какой фон был у вас нормой раньше. Смысловая единица здесь не «st выше 5%», а «st сейчас заметно выше, чем был у меня же три месяца назад, и продолжает расти» — сравнение с собственной историей, а не с чужим ориентиром.

Сверяйте тренд steal time с собственной историей нагрузки. Если параллельно растёт и ваша собственная нагрузка (больше пользователей, больше запросов), часть замедления объясняется именно этим, а не соседями — тогда апгрейд тарифа или оптимизация кода уместны наравне с разговором про хост. Если же собственная нагрузка стабильна или даже ниже, а st всё равно растёт, — вопрос почти наверняка не к вам, а к заполненности хоста.

Что делать, когда тренд подтвердился

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

Соберите график с датами перед обращением в поддержку. Голословное «стало медленнее, чем раньше» разбирают долго и часто без результата, потому что у поддержки нет способа проверить субъективное ощущение. Помесячная таблица или график среднего st за последние три-шесть месяцев — совсем другой разговор: это конкретный технический артефакт, который прямо показывает динамику конкретного физического хоста.

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

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

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

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Сколько времени нужно наблюдать, прежде чем говорить о тренде, а не о случайности?

Ориентируйтесь на несколько месяцев накопленной истории с регулярными замерами, а не на пару недель — рост плотности хоста происходит постепенно, и на коротком окне легко принять обычный недельный разброс за начало тренда. Чем длиннее история, тем увереннее вывод.

Steal time растёт, но лагов пользователи не замечают — стоит ли уже что-то делать?

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

Перенос на другой хост у того же провайдера — это гарантированное и постоянное решение?

Нет, это решение конкретной текущей проблемы, а не гарантия навсегда. Новый хост тоже будет постепенно заполняться новыми клиентами провайдера, и через какое-то время (месяцы, иногда дольше) тренд может повториться. Если это происходит регулярно у одного провайдера — сигнал уже не про конкретный хост, а про общую политику оверкоммита.

Может ли расти не steal time, а моё ощущение медленности из-за роста собственной нагрузки, которую я принимаю за чужую?

Да, поэтому лог steal time нужно смотреть вместе с собственными метриками us/sy и историей нагрузки приложения за тот же период. Если оба показателя растут параллельно, часть проблемы — ваш собственный органический рост, и его решают оптимизация и апгрейд тарифа, а не только разговор про хост.

Тариф с гарантированными vCPU полностью убирает рост steal time?

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

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →