3

WebTech

Личный кабинет

Проекты, коммерческие предложения, документы и отчёты — в одном месте.

Войти Зарегистрироваться Забыли пароль?
Масштабирование и производительность

Архитектура, которая выдерживает десятикратный рост без переписывания продукта

Снимаем baseline по метрикам, убираем состояние из приложения, разводим чтение и запись, добавляем кэш и очереди. Каждый уровень масштабирования подтверждаем нагрузочным тестом, а не предположением.

Или сразу: +7 (962) 368-39-51 Telegram

0
состояния в процессе приложения
Redis
сессии, кэш и блокировки вне PHP
p95
и p99 по каждому маршруту под нагрузкой
CDN
статика и медиа отдаются у края сети
Задачи

Где SaaS упирается в потолок

Причины, по которым вторая реплика приложения не помогает, а счёт за инфраструктуру растёт быстрее выручки.

Состояние живёт внутри процесса

Сессии в файлах, загруженные файлы на локальном диске, прогретый кэш в памяти — вторая копия приложения видит другой мир, и балансировщик ломает сценарии.

База данных — единая точка конкуренции

Аналитические выборки и отчёты конкурируют за те же ресурсы, что и запись заказов, а блокировки строк выстраивают запросы в очередь.

Кэш без стратегии инвалидации

Данные в Redis живут дольше, чем правда в базе, а одновременный прогрев одного ключа роем запросов роняет базу в момент сброса.

Тяжёлые задачи висят в HTTP-запросе

Генерация отчёта, выгрузка в Excel, синхронизация с 1С или рассылка выполняются на запросе пользователя и держат PHP-воркер минутами.

Оптимизируют наугад, без метрик

Правят код там, где «кажется медленно», вместо профилирования: настоящий узкий места — N+1 запрос, отсутствующий индекс или синхронный внешний вызов.

Автоскейлинг без согласования с БД

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

Решения

Четыре слоя масштабирования

Идём от измерения к данным и только потом к инфраструктуре: каждый слой снимает конкретное ограничение и проверяется цифрами.

Stateless-приложение и горизонтальное масштабирование

Убираем состояние из процесса, чтобы копий приложения можно было запустить сколько угодно.

  • Сессии, кэш и очереди — в Redis, а не в файлах
  • Файлы и медиа — в объектное хранилище, раздача через CDN
  • Балансировщик без sticky-сессий, health-check и корректный draining
  • Автоскейлинг по CPU, глубине очереди и числу активных соединений

Данные: репликация, пулы и шардирование

Разводим нагрузку чтения и записи и держим размер горячего набора в памяти.

  • Реплики для чтения и отчётов, мастер — только запись
  • PgBouncer или ProxySQL перед базой вместо сотен соединений
  • Партиционирование больших таблиц и шардирование по tenant_id
  • Read-your-writes там, где задержка репликации ломает сценарий

Кэширование и асинхронная обработка

Отдаём готовый ответ и убираем длинные операции из пользовательского запроса.

  • Многоуровневый кэш: in-process, Redis, HTTP-кэш ответов
  • Теги и версии ключей вместо ручного перебора при инвалидации
  • Блокировки и jitter против лавины при прогреве горячего ключа
  • RabbitMQ и очереди для отчётов, рассылок, импорта и синхронизации с 1С

Профилирование и нагрузочное тестирование

Сначала измерь: находим узкое место, правим, закрепляем результат тестом.

  • Профилирование запросов, поиск N+1 и отсутствующих индексов
  • Трассировка через OpenTelemetry, метрики в Prometheus и Grafana
  • Нагрузочные сценарии по реальному профилю трафика, а не по одной странице
  • Регрессионный нагрузочный прогон в CI/CD перед каждым релизом
Процесс

Как мы масштабируем

Стратегия «сначала измерь»: не покупаем мощность, пока не понимаем, во что именно упирается система.

  1. 01 1–2 недели

    Baseline и профилирование

    Снимаем метрики по маршрутам, считаем запросы к базе на запрос, находим N+1 и тяжёлые выборки, фиксируем текущий потолок.

  2. 02 2–3 недели

    Проектирование схемы масштабирования

    Определяем, что выносим в Redis и очереди, как разводим чтение и запись, где проходят границы шардирования и как будет работать кэш.

  3. 03 6–12 недель

    Реализация и миграция

    Делаем приложение stateless, подключаем пул соединений, реплики и очереди, переносим статику на CDN, настраиваем автоскейлинг в Kubernetes.

  4. 04 2–3 недели

    Нагрузочные тесты и запуск

    Прогоняем сценарии до пиковых значений, проверяем деградацию и восстановление, закрепляем нагрузочный тест как регрессию перед релизами.

Сначала измерь: почему масштабирование начинается с метрик

Масштабирование начинается не с закупки серверов, а с измерений. Мы снимаем baseline: p95 и p99 времени ответа по каждому маршруту, пропускную способность, число запросов к базе на один HTTP-запрос, глубину очередей, потребление CPU и памяти. Без этих цифр любая оптимизация превращается в угадывание, а автоскейлинг — в рост счёта за инфраструктуру без роста пропускной способности.

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

Что делать, когда приложение уже масштабируется, а база нет

Когда приложение стало stateless, узким местом почти всегда оказывается база данных. Мы разводим чтение и запись: горячие выборки уходят на реплики, запись остаётся на мастере, а соединения проходят через пулер — иначе сотня воркеров откроет сотни соединений и исчерпает лимит PostgreSQL или MySQL раньше, чем закончится CPU.

  • кэш на нескольких уровнях: in-process, Redis, HTTP-кэш ответов;
  • очереди в RabbitMQ для отчётов, рассылок, импорта и синхронизации с 1С;
  • партиционирование и шардирование по tenant_id, когда таблица перестаёт влезать в память;
  • CDN для статики и медиа, чтобы край сети отдавал то, что не меняется;
  • нагрузочный тест как регрессия перед каждым релизом.

Каждый шаг сопровождается метриками в Prometheus и трассировкой через OpenTelemetry: решение о следующем уровне масштабирования принимается по данным, а не по ощущениям.

Частые вопросы

С измерения. Мы снимаем профиль нагрузки: p95 и p99 по маршрутам, число запросов к базе, самые тяжёлые выборки, глубину очередей. В большинстве случаев первый прирост даёт не инфраструктура, а устранение N+1 запросов и отсутствующих индексов. И только после этого имеет смысл добавлять реплики и копии приложения.

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

Она делает копии приложения взаимозаменяемыми. Сессии, кэш и блокировки живут в Redis, файлы — в объектном хранилище, поэтому балансировщику не нужны sticky-сессии, а оркестратор может поднимать и гасить реплики в любой момент. Без этого шага автоскейлинг либо не работает, либо ломает пользовательские сценарии при переключении.

Правильный кэш имеет измеримый hit ratio и предсказуемую инвалидацию: ключи версионируются или группируются тегами, а не сбрасываются целиком по расписанию. Мы отдельно закрываем лавину при прогреве горячего ключа — блокировкой на время пересчёта и jitter в TTL, иначе одновременный сброс кэша обрушивает базу запросами.

Технические основы: другие темы

Смежные технические темы, с которыми эта задача обычно решается в одном проекте.

Узнаем, где ваша система упрётся в потолок

Разберём профиль нагрузки и предложим план масштабирования по слоям — с метриками, по которым будет видно результат.