Масштабирование SaaS-продукта: находим узкое место и растим платформу по ступеням

Масштабирование SaaS-продукта начинается не с микросервисов и не с новых серверов, а с замера: что именно замедляется, при каком росте и у кого из клиентов. Мы берём живую платформу, находим три-четыре места, которые дают почти всю нагрузку, и чиним их от дешёвого к дорогому: запросы, кэш, фоновые задачи, разделение клиентов.

Обследование — 200 000 ₽, 2–3 неделиСначала замеры на ваших данных, потом правкиИсходный код в вашем репозитории с первого коммита

С чем приходят

Признаки, что продукт вырос из первой архитектуры

Тормозит в часы пик, а ночью всё хорошо

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

Каждый новый крупный клиент — отдельная доработка

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

Миграции стали событием

Изменение структуры базы делают ночью и с остановкой сервиса, потому что таблица стала большой, а как менять её на ходу, никто не проверял.

Сервер добавили, а легче не стало

Мощности подняли дважды, а время ответа почти не изменилось: предел был в блокировке, в числе соединений с базой или в одном запросе, а не в процессоре.

Оси роста

Что растёт и что ломается первым: пять осей роста B2B-продукта

Рост бывает разным, и у каждого вида своё первое узкое место. Поэтому «масштабировать» без уточнения «что именно растёт» нельзя.

Что растёт
Что ломается первым
Как замеряем
Что делаем
Что растётОбъём данныхзаписей в больших таблицах
Что ломается первымЗапросы без индекса, отчёты, читающие таблицу целиком, миграции, которые блокируют таблицу
Как замеряемЖурнал медленных запросов и планы выполнения на копии боевых данных
Что делаемИндексы под реальные запросы, архив старых записей, секционирование самой большой таблицы, отчёты на отдельной реплике
Что растётОдновременная работапользователей в одну минуту
Что ломается первымПул соединений с базой, блокировки строк, тяжёлые операции в основном потоке запроса
Как замеряемНагрузочный сценарий по реальному профилю запросов, а не равномерный поток
Что делаемНесколько экземпляров приложения, кэш, перенос тяжёлых операций в фон, ограничение числа обращений
Что растётИнтеграции клиентоввызовов API и вебхуков
Что ломается первымОдин клиент с обменом раз в минуту занимает ресурсы, рассчитанные на сотню таких же
Как замеряемЧисло обращений к API по ключам и время ответа по каждому клиенту
Что делаемЛимиты по ключу и по тарифу, очередь исходящих вебхуков с повторами, пакетные операции вместо поштучных
Что растётТребования крупных клиентовопросники, вход, изоляция
Что ломается первымПоявляется клиент, который просит отдельную базу, вход через свой каталог или журнал по запросу
Как замеряемРеестр требований из опросников клиентов и состав того, что уже закрыто
Что делаемСмешанная схема: основная масса на общей схеме, отдельным клиентам отдельные базы, вход через SSO как подключаемый модуль
Метод

Как мы ищем узкое место: сначала замер, потом правка

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

Профиль запросов

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

Нагрузочная модель по вашему профилю

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

Порядок исправлений

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

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

Лестница мер

Шесть мер масштабирования от дешёвой к дорогой и когда каждая нужна

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

Мера
Что даёт
Что платите
Когда пора
МераИндексы и переписанные запросыпервое, что проверяем
Что даётСамая частая причина «медленно»: запрос читает больше строк, чем нужно
Что платитеИндексы замедляют запись и занимают место; их набор нужно пересматривать
Когда пораВсегда, до любых других мер
МераКэшповторяющиеся чтения
Что даётРедко меняющиеся ответы (справочники, настройки, права) не идут в базу каждый раз
Что платитеНужно решить, когда запись в кэше считается устаревшей; ошибка показывает пользователю старое значение
Когда пораОдни и те же данные читают много раз, а меняют редко
МераФоновые задачитяжёлое не в потоке запроса
Что даётИмпорт, отчёты, рассылки, расчёты выполняются в очереди, пользователь получает ответ сразу
Что платитеПовторы без дублей, видимость недоставленного, статус задачи для пользователя
Когда пораОперация длится дольше, чем пользователь готов ждать у экрана
МераРеплика для чтенияразгрузка основной базы
Что даётОтчёты и списки читаются с копии, запись остаётся на основной базе
Что платитеКопия отстаёт на какое-то время; в сценариях «записал и сразу прочитал» читать надо с основной
Когда пораОтчёты мешают основной работе, запросов на чтение заметно больше, чем на запись
МераРазнесение клиентов по базамклиент как единица деления
Что даётГруппы клиентов живут в разных базах или схемах; нагрузка и сбой одной группы не касаются других
Что платитеРеестр клиентов, маршрутизация запросов, миграции по каждой базе, перенос клиента между группами
Когда пораОдна база не справляется даже после предыдущих мер, либо крупным клиентам нужна отдельная
МераВыделение сервисачасть системы отдельно
Что даётСамая независимая часть (уведомления, формирование документов, приём вебхуков) работает и масштабируется отдельно
Что платитеСеть вместо вызова функции, версии интерфейсов, наблюдаемость
Когда пораЧасть системы живёт по другим правилам нагрузки или надёжности. Подробнее — на странице о <a href="../mikroservisnaya-arhitektura-i-vysokaya-nagruzka/">микросервисах и высоконагруженных системах</a>
Шумный сосед

Один клиент не должен тормозить остальных

В B2B-продукте нагрузка распределена неравномерно: небольшая часть клиентов создаёт большую часть запросов. Это не ошибка, это свойство продукта, и к нему готовятся заранее.

«Шумный сосед» — клиент, чья операция занимает общие ресурсы. Типичный случай: ночью запущен импорт на большой объём данных, и утром у всех остальных медленно открываются списки. Чинят это не мощностью, а правилами.

Лимиты по клиенту

  • Обращения к API. Лимит по ключу и по тарифу с понятным ответом «подождите» и временем, через которое можно повторить. Без этого интеграция клиента с ошибкой в цикле выглядит для сервера как атака.
  • Параллельные задачи. Каждому клиенту доступно ограниченное число одновременных тяжёлых задач, чтобы одна организация не заняла всех исполнителей.

Очередь с честным распределением

Если очередь одна на всех, большой клиент ставит в неё сотню задач, и маленькие ждут за ними. Задачи берутся по очереди от разных клиентов, а не подряд, и у тяжёлых операций отдельные исполнители, чтобы не мешать быстрым.

Живая платформа

Миграции и перенос данных без остановки сервиса

На платформе с платящими клиентами «остановим на ночь» перестаёт быть нормальным ответом. Менять структуру данных приходится на ходу, и для этого есть последовательность.

Расширить, перенести, сжать

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

Перенос крупного клиента в отдельную базу

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

Что делаем

Из чего состоит работа и сколько она стоит

Цены — по тарифам. Точная цена только у обследования, дальше вилка, которая сужается по его результатам. Остановиться можно после любой ступени.

Обследование: профиль нагрузки и план

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

200 000 ₽ · 2–3 недели

Обследование: несколько систем и контуров

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

350 000 ₽ · 3–4 недели

Лёгкий пилот: исправление первого узкого места

Индексы, переписанные запросы, кэш, перенос одной тяжёлой операции в фон. Замер до и после на ваших данных, протокол испытаний.

150 000 – 400 000 ₽ · 2–8 недель

Тяжёлый пилот: перестройка слоя данных

Секционирование, реплика для чтения, отдельное хранилище для отчётов, лимиты и очереди по клиентам, подготовка переноса клиентов в отдельные базы.

400 000 – 1 200 000 ₽ · 2–3 месяца

Вывод в эксплуатацию

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

от 1 500 000 ₽ этапами по 300 000 – 700 000 ₽ · от 3 месяцев

Сопровождение

Мониторинг, разбор инцидентов, плановые доработки с пакета на 60 000 ₽. Сверх пакета — 5 000 ₽ в час.

20 000 / 60 000 / 120 000 ₽ в месяц
Процесс

Как идёт работа

1 неделя — Доступы и сбор данных

Получаем доступ к журналам, метрикам и копии базы (обезличенной, если в ней персональные данные), договариваемся, кто отвечает за вашу инфраструктуру. Ничего не меняем.

1–2 недели — Замеры и документ с планом

Профиль запросов, нагрузочный сценарий на копии, первый отказ под нагрузкой. На выходе перечень узких мест, меры с оценкой и порядок; здесь решаем, нужен ли пилот.

От 2 недель — Исправления по одной

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

Перед выходом — Испытание и релиз

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

Дальше — рост или сопровождение

Следующие меры по ступеням, либо передаём инструкцию и мониторинг вашей команде, либо сопровождаем сами.

Цена

Что двигает цену внутри вилки

Состояние наблюдаемости

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

Число окружений и клиентов с особыми условиями

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

Зависимость от чужих систем

Если узкое место внутри обмена с внешней системой, чинить приходится и процесс обмена, и согласование изменений с её владельцем.

Контроль

Что остаётся у вас и чего мы не делаем

Остаётся у вас

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

Мы этого не делаем

  • Не обещаем конкретного роста производительности и не пишем в договор процент доступности: он зависит от вашей инфраструктуры и чужих систем.
  • Не дежурим круглосуточно и не следим за платформой в ночные часы.
  • Не берёмся перестроить платформу, для которой нужна команда в несколько десятков человек. Берём одно узкое место и один контур.
  • Не проводим аттестацию, лицензии ФСТЭК у нас нет. Не берём работы дешевле 150 000 ₽.
Граница

Масштабирование, архитектура или аудит кода: где проходит граница

Эта страница про рост уже работающего продукта: замеры, узкие места, миграции, нагрузка от крупных клиентов. Если платформы ещё нет, начинают с разработки SaaS-платформы, а для первой версии — с состава и ограничений, как в статье «Как разработать SaaS с нуля».

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

Порядок узких мест подробно разобран в статье «Как масштабировать SaaS и B2B-продукт».

Инструменты

На чём работаем

Замеры и данные
  • Журнал медленных запросов и планы выполнения PostgreSQL
  • Нагрузочные сценарии на Python или Go по реальному профилю запросов
  • Метрики и панели в Prometheus и Grafana, если нет своих
  • Трассировка запросов через приложение и фоновые задачи
Приложение и развёртывание
  • Python (Django, FastAPI) или Go; ваш стек сохраняем
  • Redis или совместимое хранилище для кэша и лимитов; очередь в PostgreSQL или RabbitMQ
  • Docker, Nginx или другой балансировщик, GitLab CI
  • Репликация и секционирование средствами PostgreSQL
Материалы

Материалы по теме

Статья

Как масштабировать SaaS и B2B-продукт: узкие места по порядку

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

  • Узкие места по порядку
  • Что замерить
  • Чего не делать
Читать →
Статья

Мультиарендность в SaaS: как разделить данные клиентов

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

  • Три схемы
  • Политики на уровне строк
  • Тесты изоляции
Читать →
Статья

Микросервисы или монолит: как выбрать

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

  • Критерии выбора
  • Модульный монолит
  • Цена перехода
Читать →
Заявка

Разберём, где ваша платформа упирается

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

Спасибо, заявка отправлена. Ответим в течение рабочего дня.

Не удалось отправить. Напишите в телеграм или позвоните.

Вопросы

Частые вопросы: масштабирование SaaS-продукта

С чего начинается масштабирование SaaS-продукта?

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

Сколько стоит масштабирование SaaS-платформы?

Обследование стоит 200 000 ₽ за один-два процесса и 350 000 ₽ при нескольких системах; оно вычитается из первого этапа, если продолжаете с нами. Исправление первого узкого места укладывается в лёгкий пилот (150 000–400 000 ₽, 2–8 недель), перестройка слоя данных — в тяжёлый (400 000–1 200 000 ₽, 2–3 месяца). Вывод в эксплуатацию начинается от 1 500 000 ₽ и режется на этапы по 300 000–700 000 ₽.

Нужно ли переходить на микросервисы, чтобы масштабироваться?

Чаще нет. Многие продукты выдерживают рост на настроенном монолите: индексы, кэш, фоновые задачи, несколько экземпляров приложения, реплика для чтения. Сервисы выделяют, когда часть системы живёт по другим правилам нагрузки или надёжности. Решение принимается по замерам и записывается с причинами.

Можно ли перенести крупного клиента в отдельную базу?

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

Остановится ли платформа на время работ?

Мы стараемся этого не допускать. Изменения структуры данных идут в три релиза (расширить, перенести, сжать), выход на боевую платформу назначается на тихие часы с планом возврата. Если операция без остановки невозможна, согласуем окно заранее.

Как вы проверяете, что стало лучше?

Замером до и после на одних и тех же данных и по одному сценарию. Если время ответа не изменилось, правку считаем неудавшейся и откатываем. Нагрузочные сценарии остаются у вас. Конкретный рост производительности заранее не обещаем: он зависит от причины и от данных.

Где будет работать платформа и кому принадлежит код?

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

Вы работаете только в Ростове-на-Дону?

Мы в Ростове-на-Дону, работаем с заказчиками по всей России: удалённо и в вашем контуре. Доступ к системам и обследование согласуем на старте с вашей службой безопасности.