сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · SRE и надёжность

Ёмкость и планирование нагрузки

Ёмкость и очередь

Смоделировал обычную очередь: один обработчик, запрос обслуживается в среднем 10 миллисекунд, запросы приходят случайно. При загрузке 50% среднее время ответа 20,1 миллисекунды. При 90% - 99,2. То есть нагрузка выросла меньше чем вдвое, а ждать стали в пять раз дольше. А квантиль 0,99 - значение, ниже которого лежат 99% запросов, - вырос с 92,8 миллисекунды до 463,6.

Стержень: время ответа растёт не линейно с нагрузкой, а разгоняется у предела; поэтому планируют запас, а не «загрузим до сотни».

// Формулировки: «почему при 90% загрузки всё тормозит?», «сколько серверов нужно?», «как готовиться к пику?»

Почему нельзя загружать под завязку

Причина в случайности. Запросы приходят не ровным строем, а пачками, и обслуживаются тоже за разное время. Когда обработчик свободен половину времени, пачка рассасывается быстро. Когда он занят 90% времени, каждая пачка становится очередью, а очередь - это ожидание, которое добавляется к обслуживанию.

Полные числа моего замера: загрузка 50% - среднее 20,1 и квантиль 0,99 равен 92,8 миллисекунды; 70% - 32,8 и 146,3; 80% - 50,7 и 233,4; 90% - 99,2 и 463,6; 95% - 190,0 и 797,8. Обрати внимание: от 90% к 95% нагрузка выросла на пять процентов, а время ответа - вдвое.

// Отсюда практика планирования. Целятся в загрузку 50-70% в обычное время, чтобы был запас на пик и на потерю части мощности. Считают не по среднему, а по пиковой минуте: сервис, живущий в среднем на 40%, в вечерний час может быть на 85%. И помнят, что при отказе одной из трёх машин оставшиеся получают полуторную нагрузку - если они уже работали на 70%, то мгновенно окажутся за сотней.

загрузка
доля времени, которую обработчик занят
очередь
ожидание перед обслуживанием; именно она разгоняет время ответа

Сколько нужно и откуда берётся число

Базовый расчёт устроен просто. Если один экземпляр обрабатывает запрос за 10 миллисекунд, то на одном потоке это 100 запросов в секунду. Нужно держать 2000 - значит, нужно 20 обработчиков при стопроцентной загрузке, а с целевой загрузкой 60% уже 34. Плюс запас на отказ: если хотим пережить потерю одной машины из пяти, добавляем ещё четверть.

Второй вход в тот же расчёт - через число одновременных запросов. Среднее число запросов «внутри» сервиса равно потоку, умноженному на время обработки: 2000 в секунду по 50 миллисекунд - это 100 запросов одновременно. Это же число задаёт размеры пулов - заранее подготовленных запасов соединений к базе, потоков и рабочих мест.

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

пропускная способность
сколько запросов в секунду тянет один обработчик
число одновременных запросов
поток, умноженный на время обработки; задаёт размеры пулов

Пики и скорость появления ёмкости

Готовность к пику держится на двух вопросах сразу: «сколько» и «как быстро». Автомасштабирование выглядит спасением, пока не посчитаешь время реакции: заметить рост (десятки секунд), принять решение, запустить машину или контейнер, дождаться прогрева приложения и наполнения кэшей. В сумме легко набегают минуты, а пик распродажи или рассылки приходит за секунды.

Отсюда разделение. Плавные предсказуемые изменения (день-ночь, будни-выходные) закрывают автомасштабированием. Известные заранее пики - предварительным увеличением по расписанию, за час до события. Внезапные всплески - запасом, который уже стоит и прогрет, плюс ограничением частоты запросов и очередями, которые превращают отказ в ожидание.

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

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

Как отвечать: «Загрузка процессора 85%, время ответа выросло вдвое. Докупать сервера?»

Сначала проверю, что упёрлись именно в процессор, а не в число соединений к базе, диск или чужой сервис - узкое место редко там, где смотрят в первую очередь. Но само по себе поведение нормальное и ожидаемое: время ответа растёт не линейно, а разгоняется у предела. Я моделировал очередь с обслуживанием по десять миллисекунд: при загрузке 50% среднее время 20 миллисекунд, при 90% - 99, а от 90% к 95% оно ещё удваивается. То есть последние проценты загрузки стоят дороже всех предыдущих. Поэтому целюсь в 50-70% в обычное время и считаю по пиковой минуте, а не по среднему за сутки. И обязательно закладываю запас на отказ: если из трёх машин выпадет одна, оставшиеся получат полуторную нагрузку, и при исходных 70% они мгновенно окажутся за сотней.

Ответ сначала ставит под сомнение диагноз, потом объясняет нелинейность числами и заканчивается запасом на отказ. Это разговор про планирование, а не про покупку железа.

На чём валятся

  • Планируют загрузку под 90% и удивляются росту времени ответа.
  • Считают по среднему за сутки, а не по пиковой минуте.
  • Не закладывают запас на отказ: выпадение одной машины из трёх добавляет остальным половину нагрузки.
  • Надеются на автомасштабирование там, где пик приходит быстрее, чем поднимается экземпляр.
  • Верят арифметике без нагрузочного испытания и упираются в узкое место, которого не было в расчёте.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 6, остальные разбираются в тренажёре.

  1. #dvo_capacity1 / 5
    Планируем ёмкость по средней нагрузке за месяц. Что не так с этим подходом?
    A)Среднее считают по неверному окну: нужно брать неделю
    B)Средние по разным сервисам не складываются
    C)Систему кладут пики, а среднее их прячет
    D)Среднее не учитывает рост числа пользователей за месяц
    показать ответ и разбор
    +C)Систему кладут пики, а среднее их прячет

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

  2. #dvo_capacity2 / 5
    При загрузке 60% сервис отвечает за 100 мс, при 85% — за 800 мс, хотя ресурсы ещё есть. Почему так резко?
    A)Ошибка измерений: на высокой нагрузке метрики запаздывают
    B)У предела очередь растёт нелинейно
    C)Сборщик мусора включается только под нагрузкой и добавляет паузы
    D)Балансировщик при высокой загрузке переключается на резервные узлы
    показать ответ и разбор
    +B)У предела очередь растёт нелинейно

    // разбор: Время ответа складывается из обработки и ожидания в очереди. Пока утилизация невелика, очередь пуста и виден только сам расчёт; ближе к пределу каждая новая единица нагрузки добавляет всё больше ожидания — рост гиперболический. Потому целятся не в стопроцентную загрузку, а в 60-70% с запасом: он оплачивает всплески, деплои и отказ части мощностей.

  3. #dvo_capacity3 / 5
    Ожидается всплеск от рассылки: трафик вырастет вшестеро за минуту. Почему нельзя положиться на автоскейл?
    A)Автоскейл ограничен числом реплик в манифесте
    B)Метрики нагрузки собираются раз в минуту и опоздают
    C)Правила скейлинга не умеют реагировать на резкий рост
    D)Ёмкость приезжает минутами, зависимости — дольше
    показать ответ и разбор
    +D)Ёмкость приезжает минутами, зависимости — дольше

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

  4. #dvo_capacity4 / 5
    Почему сервис не гоняют в проде близко к 100% утилизации, даже если «ресурсы же есть»?
    A)Так требуют лицензии на процессоры облака
    B)У 100% выше энергопотребление на ватт
    C)Иначе метрики утилизации перестают собираться
    D)Нужен запас на всплески, отказ узла и деградацию
    показать ответ и разбор
    +D)Нужен запас на всплески, отказ узла и деградацию

    // разбор: Работа на пределе не оставляет запаса: любой всплеск трафика, отказ ноды (её нагрузка переедет на соседей) или деградация зависимости мгновенно перегружают систему, а у предела задержка растёт нелинейно. Поэтому держат headroom — целевую утилизацию заметно ниже 100% (часто 50–70%), чтобы пережить пик и потерю части мощности без падения. Запас — это не «простой ресурсов», а купленная устойчивость.

  5. #dvo_capacity5 / 5
    Нужно узнать реальный потолок сервиса до того, как в него упрётся прод. Как это выяснить?
    A)Прикинуть потолок по загрузке CPU на глаз
    B)Подождать реального пика и замерить в проде
    C)Нагрузочным тестом найти «колено» — где растёт задержка
    D)Взять цифры из документации библиотеки/фреймворка
    показать ответ и разбор
    +C)Нагрузочным тестом найти «колено» — где растёт задержка

    // разбор: Потолок находят нагрузочным тестированием: под контролем повышают запросы в секунду (или конкурентность) на реалистичном трафике и смотрят, где задержка/ошибки начинают расти нелинейно — это «колено», за ним система деградирует. Так узнают безопасный рабочий уровень и куда ставить лимиты/автоскейл заранее, а не ценой прод-инцидента. Прикидки по CPU и цифры из доков не учитывают ваш профиль нагрузки.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.