Сервис масштабируют добавлением экземпляров, но его пропускная способность перестаёт расти. Какой механизм обычно объясняет этот предел?
Обычно предел возникает из-за узкого места, которое не масштабируется вместе с числом экземпляров: общей базы данных, блокировки, ограниченного пула соединений, одной очереди или внешнего лимита. Новые экземпляры увеличивают конкуренцию за этот ресурс, поэтому суммарная пропускная способность перестаёт расти, а задержки могут увеличиваться.
Горизонтальное масштабирование появилось как практический способ обходить ограничения одного мощного узла: вместо постоянного увеличения его ресурсов нагрузку распределяют между несколькими экземплярами. Такой подход особенно эффективен для независимых запросов без общего изменяемого состояния.
Однако распределение вычислений не устраняет ограничения общей системы. Если часть обработки остаётся последовательной или обращается к единому ресурсу, она становится пределом всей архитектуры. Это соответствует идее закона Амдала: ускорение ограничено долей работы, которую нельзя эффективно распараллелить.
Предположим, один экземпляр сервиса обрабатывает 100 запросов в секунду. После добавления второго экземпляра ожидается почти 200 запросов в секунду, но фактический результат — 120, а затем при добавлении новых экземпляров рост прекращается.
Причина может быть в общей базе данных, исчерпании её соединений, конфликте блокировок, последовательной обработке одного раздела очереди или квоте внешней системы. Ошибка в диагностике приводит к бесполезному увеличению числа экземпляров: стоимость растёт, а SLO по задержке и доступности ухудшается.
Сначала нужно разделить вычислительную ёмкость экземпляров и ёмкость общих зависимостей. Если экземпляры загружены слабо, но растут задержки запросов к базе данных или длина очереди ожидания соединения, ограничение находится не в CPU сервиса.
Механизм обычно выглядит так: каждый новый экземпляр отправляет часть запросов в общий ресурс; его загрузка приближается к насыщению, растёт время ожидания, а полезная работа вытесняется очередями и повторными попытками. После насыщения увеличение параллелизма почти не добавляет завершённых операций, но увеличивает незавершённые запросы и задержку.
Для поиска предела сравнивают при разных размерах пула:
Масштабирование экземпляров помогает только тогда, когда узкое место действительно распределяется. Иначе применяют другие меры: разбивают горячий раздел, увеличивают ёмкость зависимости, кэшируют безопасные для кэширования данные, уменьшают объём операций или устраняют лишнюю синхронизацию.
У каждого решения есть компромиссы. Кэш снижает нагрузку, но создаёт проблему устаревших данных; увеличение базы данных может быть дорогим и не устранить горячий ключ; ослабление блокировок повышает параллелизм, но может изменить гарантии согласованности. Поэтому изменение выбирают по измеренному ограничению и проверяют нагрузочным тестом.
Сервис заказов масштабировали с шести до двадцати экземпляров. CPU оставался около 35%, но p95 задержки вырос с 180 до 900 миллисекунд, а база данных достигла максимального числа одновременных соединений. Анализ показал, что большинство запросов конкурировало за один горячий раздел данных.
Рассматривались три варианта. Увеличение числа экземпляров было быстрым, но только усиливало конкуренцию. Увеличение размера базы давало запас, однако не устраняло перекос нагрузки и повышало стоимость. Добавление кэша уменьшало чтения, но было рискованным для данных, требующих немедленной согласованности.
Выбрали перенос горячих записей в более равномерно распределяемые разделы и ограниченное кэширование справочных данных. После этого добавление экземпляров снова увеличивало пропускную способность, а задержка вернулась к целевому диапазону. Результат подтвердил, что прежним пределом были общий ресурс и неравномерное распределение нагрузки, а не вычислительная мощность сервиса.
Да. Поток может большую часть времени ждать сеть, базу данных, блокировку, пул соединений или внешний сервис. В таком случае CPU простаивает, хотя пользовательская задержка растёт. Поэтому загрузку CPU нельзя использовать как единственный критерий достаточной ёмкости; нужно измерять время ожидания и состояние зависимостей.
Каждый экземпляр создаёт дополнительную конкуренцию за общий ресурс. Растут число соединений, блокировок, сетевой трафик, межузловая координация или размер очереди. Если ресурс уже близок к насыщению, новые экземпляры увеличивают накладные расходы и время ожидания, не увеличивая число завершённых операций.
Нет. Высокая загрузка не всегда ограничивает пропускную способность: компонент может иметь запас по фактическому времени ответа или масштабироваться независимо. Узкое место — это ресурс, увеличение ёмкости которого заметно повышает пропускную способность либо снижает задержку при данном профиле нагрузки. Вывод подтверждают контролируемым изменением, метриками очередей и повторным нагрузочным тестом.