Облако для продакшена. Что показывают steal, await и реальная полоса?
Два провайдера, одинаковая строка в тарифе: 4 vCPU, 8 ГБ, 100 ГБ SSD, гигабит. Цена расходится на 15 процентов, и непонятно почему. Через неделю тестов выясняется, что p99 отличается в разы. Тариф описывает то, что выделено виртуально. Что происходит в железе, туда не попадает.
Почему синтетика не отвечает на вопрос? Geekbench и sysbench меряют потолок за короткий тест. Продакшен работает иначе: нагрузка неровная, соседи по ноде непредсказуемы. Провайдеры делают оверкоммит, и пока суммарная нагрузка умеренная, все хорошо. Стоит нескольким машинам дать всплеск разом, растет steal, удлиняется дисковая очередь, канал упирается в шейпер. Короткий тест может не попасть в это окно. Нужно от получаса нагрузки, а на суточные паттерны от 24 часов.
CPU steal. Steal это доля времени, когда vCPU готов работать, но гипервизор не дает ему физическое ядро. Приложение получает задержку без видимой причины: процессор загружен, работа не идет.
vmstat 1 30
procs -----------memory---------- ---cpu---
r b swpd free buff cache us sy id wa st
2 0 0 512344 81920 210488 31 4 58 1 6
Колонка st справа. Шесть процентов несколько строк подряд это не шум. Разбивку по ядрам дает mpstat -P ALL 1 10, длинный срез пишут в файл через sar -u 1 3600 и сравнивают часы между собой.
До процента можно не смотреть. От одного до пяти наблюдать, если нагрузка чувствительна к задержкам. От пяти до десяти хвосты страдают. Выше десяти это разговор с поддержкой про ноду и тариф.
Для транскодирования и компиляции steal переводится во время выполнения почти линейно. Для API и запросов к базе иначе: медиана держится, а p99 растет, потому что в моменты steal запросы копятся в очереди. Отдельная история это всплески до 20 процентов на пару секунд при спокойном фоне. Такой скачок опаснее ровного высокого steal, он тянет каскад таймаутов.
Диск. Публикуемые IOPS измерены в идеальных условиях и под смешанной нагрузкой мало о чем говорят. Мониторинг запускают параллельно с тестом.
iostat -xz 1 10
В выводе важны два числа: await это время запроса вместе с ожиданием в очереди, avgqu-sz это глубина очереди. Растет второе, следом первое. Профиль OLTP проверяют так:
fio --name=rand4k --rw=randrw --rwmixread=70 --bs=4k --direct=1 \
--numjobs=4 --iodepth=32 --size=4G --runtime=60 \
--time_based --ioengine=libaio --group_reporting
Флаг direct обязателен, без него тест уедет в страничный кеш и покажет память вместо диска. В отчете смотрите iops и clat p99, именно второе объясняет хвосты запросов. Ориентир для средней базы это 5000 IOPS на чтении 4К при await ниже 2 мс, для нагруженной 20000 при await ниже миллисекунды.
Очередь выше восьми под OLTP это первый признак насыщения. Загрузка под 100 процентов для SSD не приговор, тревожно когда вместе с ней растет await. У дисков с лимитом IOPS порог срабатывает раньше насыщения железа, и покажет это именно await.
Сеть. Заявленный гигабит это верхний предел, а не гарантия. Шейпинг под нагрузкой в документации обычно не описан.
iperf3 -c 10.0.0.5 -t 60 -P 4
mtr --report --report-cycles 100 10.0.0.5
Четыре потока нужны потому, что один упирается в размер окна и RTT, а не в канал. Минута нужна, чтобы поймать burst лимит: полная полоса первые пятнадцать секунд и просадка дальше это он. Потери на одном промежуточном хопе при чистом трафике дальше это деприоритизация ICMP роутером. Потери подряд на нескольких хопах уже другое.
Проверьте MTU. Overlay сети добавляют заголовок к каждому пакету, 1500 превращаются в 1450, а пакеты с флагом DF молча теряются.
ping -M do -s 1472 10.0.0.5
Порядок проверки. Срез в покое сразу после деплоя, он же точка отсчета. Затем steal под боевой нагрузкой. Дальше fio с профилем приложения и iostat в соседнем терминале. Потом сеть. И наблюдение сутки или трое, иначе суточный паттерн конкуренции пройдет мимо.
Одинаковые характеристики не означают одинаковую производительность. Steal, await и реальная полоса измеряются за несколько часов.