После потери одной зоны оставшиеся экземпляры формально здоровы, но сервис начинает тайм-аутиться. Какой механизм планирования мощности объясняет это?
Это объясняется отсутствием резерва мощности для отказа. Если система в штатном режиме использует почти всю доступную производительность, то после потери зоны оставшиеся экземпляры получают дополнительную нагрузку, входят в режим насыщения, а задержки и число таймаутов резко растут.
Надёжная конфигурация обычно планируется по принципу N+1 или с заданным запасом: после отказа одной зоны оставшаяся инфраструктура должна выдерживать целевую нагрузку в пределах установленного SLO.
Высокодоступные системы изначально строились с резервированием не только данных и экземпляров, но и вычислительной ёмкости. Простого наличия резервного узла недостаточно: он должен иметь возможность принять трафик без перехода всей системы в перегруженное состояние.
Практика показала, что отказоустойчивость нельзя оценивать только по факту переключения трафика. Нужно проверять, сохраняются ли после отказа требуемые задержка, пропускная способность и доля успешных запросов.
Предположим, три зоны обслуживают нагрузку равномерно, а каждая занята на 70%. После отказа одной зоны нагрузка перераспределяется между двумя оставшимися, и их загрузка становится примерно 105% от прежней номинальной ёмкости. Формально экземпляры продолжают работать, но очереди растут, запросы дольше ждут CPU, соединения или внешние зависимости, а затем истекают по таймауту.
Особенно опасна нелинейность около насыщения: небольшое увеличение нагрузки при почти полной занятости ресурса может вызвать непропорциональный рост задержки. Поэтому проверка «все реплики запущены» не доказывает, что система переживёт отказ зоны.
Сначала определяют целевую нагрузку после отказа: например, количество запросов в секунду, профиль запросов и допустимые значения задержки. Затем измеряют производительность оставшейся инфраструктуры под этим профилем и проверяют, укладывается ли она в SLO.
Варианты планирования:
Процент загрузки сам по себе не является универсальной гарантией. CPU может быть свободен, пока узким местом остаются база данных, лимит соединений, пропускная способность сети или очередь запросов. Поэтому тестируют весь критический путь и отдельно проверяют состояние зависимостей.
Резерв должен учитывать не только среднюю нагрузку, но и пики, неравномерное распределение трафика, прогрев кэшей, время масштабирования и одновременные отказы. Слишком большой запас повышает стоимость, а слишком маленький создаёт риск каскадной деградации. Автомасштабирование снижает расходы, но не всегда достаточно быстро реагирует на внезапный отказ, поэтому для критичных систем часть резерва держат заранее.
Сервис работал в трёх зонах с равномерным распределением запросов. В штатном режиме средняя загрузка CPU составляла 60%, но после отключения одной зоны p99 задержки превысил SLO: оставшиеся экземпляры получили весь трафик, а база данных уже работала близко к пределу.
Команда рассмотрела три варианта. Увеличение числа экземпляров только в штатном режиме было дешёвым, но не гарантировало мгновенного покрытия отказа. Полностью удвоить инфраструктуру давало большой запас, однако стоимость была чрезмерной. Перенос части нагрузки на менее важный функционал освобождал ресурсы, но усложнял поведение системы.
Выбрали постоянный резерв уровня N+1, ограничение тяжёлых фоновых операций во время аварии и регулярный тест отказа зоны. После изменения оставшиеся зоны выдерживали целевую нагрузку, а деградация необязательных задач не нарушала пользовательский SLO. Цена решения выросла умеренно по сравнению с полным удвоением, зато результат проверялся измеримым сценарием отказа.
1. Достаточно ли поддерживать среднюю загрузку экземпляров ниже 70%?
Нет. Средняя загрузка может скрывать неравномерное распределение трафика, пики и насыщение другого ресурса. Для оценки резерва нужно проверять максимальную или распределённую нагрузку, профиль запросов, задержки и состояние зависимостей после конкретного отказа.
2. Почему быстрое автомасштабирование не всегда заменяет заранее выделенный резерв?
Масштабирование требует времени: нужно обнаружить проблему, принять решение, получить ресурсы, запустить экземпляры и прогреть их. За этот период система может уже нарушать SLO или породить очередь, которую новые экземпляры не успеют быстро обработать. Поэтому автомасштабирование полезно для длительного роста нагрузки, а заранее доступная ёмкость — для резких отказов.
3. Нужно ли резервировать мощности всех зависимостей, а не только вычислительных экземпляров?
Да. Если после отказа зоны сервис увеличит число запросов к базе, кэшу или внешнему API, зависимость также должна выдержать новый профиль нагрузки. Иначе вычислительный резерв лишь перенесёт узкое место и может ускорить перегрузку зависимости; проверка должна охватывать весь критический путь.