Состояние живёт внутри процесса
Сессии в файлах, загруженные файлы на локальном диске, прогретый кэш в памяти — вторая копия приложения видит другой мир, и балансировщик ломает сценарии.
Выберите тему — соберём контекст
Снимаем baseline по метрикам, убираем состояние из приложения, разводим чтение и запись, добавляем кэш и очереди. Каждый уровень масштабирования подтверждаем нагрузочным тестом, а не предположением.
Или сразу: +7 (962) 368-39-51 Telegram
Причины, по которым вторая реплика приложения не помогает, а счёт за инфраструктуру растёт быстрее выручки.
Сессии в файлах, загруженные файлы на локальном диске, прогретый кэш в памяти — вторая копия приложения видит другой мир, и балансировщик ломает сценарии.
Аналитические выборки и отчёты конкурируют за те же ресурсы, что и запись заказов, а блокировки строк выстраивают запросы в очередь.
Данные в Redis живут дольше, чем правда в базе, а одновременный прогрев одного ключа роем запросов роняет базу в момент сброса.
Генерация отчёта, выгрузка в Excel, синхронизация с 1С или рассылка выполняются на запросе пользователя и держат PHP-воркер минутами.
Правят код там, где «кажется медленно», вместо профилирования: настоящий узкий места — N+1 запрос, отсутствующий индекс или синхронный внешний вызов.
Оркестратор поднимает новые копии приложения, каждая открывает свой пул соединений, и база отказывает раньше, чем заканчивается CPU.
Идём от измерения к данным и только потом к инфраструктуре: каждый слой снимает конкретное ограничение и проверяется цифрами.
Убираем состояние из процесса, чтобы копий приложения можно было запустить сколько угодно.
Разводим нагрузку чтения и записи и держим размер горячего набора в памяти.
Отдаём готовый ответ и убираем длинные операции из пользовательского запроса.
Сначала измерь: находим узкое место, правим, закрепляем результат тестом.
Стратегия «сначала измерь»: не покупаем мощность, пока не понимаем, во что именно упирается система.
Снимаем метрики по маршрутам, считаем запросы к базе на запрос, находим N+1 и тяжёлые выборки, фиксируем текущий потолок.
Определяем, что выносим в Redis и очереди, как разводим чтение и запись, где проходят границы шардирования и как будет работать кэш.
Делаем приложение stateless, подключаем пул соединений, реплики и очереди, переносим статику на CDN, настраиваем автоскейлинг в Kubernetes.
Прогоняем сценарии до пиковых значений, проверяем деградацию и восстановление, закрепляем нагрузочный тест как регрессию перед релизами.
Масштабирование начинается не с закупки серверов, а с измерений. Мы снимаем baseline: p95 и p99 времени ответа по каждому маршруту, пропускную способность, число запросов к базе на один HTTP-запрос, глубину очередей, потребление CPU и памяти. Без этих цифр любая оптимизация превращается в угадывание, а автоскейлинг — в рост счёта за инфраструктуру без роста пропускной способности.
Дальше устраняем то, что физически мешает запустить вторую копию приложения: сессии и кэш переносим в Redis, загруженные файлы — в объектное хранилище, фоновые задачи — в очереди. Пока процесс хранит состояние на локальном диске, горизонтальное масштабирование невозможно в принципе, сколько бы реплик вы ни подняли.
Когда приложение стало stateless, узким местом почти всегда оказывается база данных. Мы разводим чтение и запись: горячие выборки уходят на реплики, запись остаётся на мастере, а соединения проходят через пулер — иначе сотня воркеров откроет сотни соединений и исчерпает лимит PostgreSQL или MySQL раньше, чем закончится CPU.
Каждый шаг сопровождается метриками в Prometheus и трассировкой через OpenTelemetry: решение о следующем уровне масштабирования принимается по данным, а не по ощущениям.
С измерения. Мы снимаем профиль нагрузки: p95 и p99 по маршрутам, число запросов к базе, самые тяжёлые выборки, глубину очередей. В большинстве случаев первый прирост даёт не инфраструктура, а устранение N+1 запросов и отсутствующих индексов. И только после этого имеет смысл добавлять реплики и копии приложения.
Нет, и обычно вредно. Сначала исчерпываются более дешёвые шаги: индексы, разведение чтения и записи, пул соединений, партиционирование больших таблиц, вынос аналитики в ClickHouse. Шардирование по tenant_id усложняет транзакции и отчёты, поэтому мы идём к нему только тогда, когда горячий набор данных перестаёт помещаться в память.
Она делает копии приложения взаимозаменяемыми. Сессии, кэш и блокировки живут в Redis, файлы — в объектном хранилище, поэтому балансировщику не нужны sticky-сессии, а оркестратор может поднимать и гасить реплики в любой момент. Без этого шага автоскейлинг либо не работает, либо ломает пользовательские сценарии при переключении.
Правильный кэш имеет измеримый hit ratio и предсказуемую инвалидацию: ключи версионируются или группируются тегами, а не сбрасываются целиком по расписанию. Мы отдельно закрываем лавину при прогреве горячего ключа — блокировкой на время пересчёта и jitter в TTL, иначе одновременный сброс кэша обрушивает базу запросами.
Смежные технические темы, с которыми эта задача обычно решается в одном проекте.
Разберём профиль нагрузки и предложим план масштабирования по слоям — с метриками, по которым будет видно результат.
Cookie и аналитика
Мы используем необходимые cookie для работы сайта и форм. Аналитические cookie (Яндекс.Метрика, включая запись сессий) подключаем только с вашего согласия — от него можно отказаться. Подробнее: Политика использования cookie и обработка персональных данных.