Почему мультитенантность AI SaaS ломается при росте базы
Пока клиентов десятки, мультитенантность держится на дисциплине: один общий контур, общая база, общий пул инференса. С ростом базы клиентов эта схема отказывает сразу в нескольких местах, и каждый следующий отказ обходится дороже предыдущего — от замороженных релизов до разбора инцидента с утечкой.
Изоляция данных клиентов чаще всего обеспечена фильтром по идентификатору тенанта в коде приложения. Одна забытая ветка запроса, один отчёт, написанный в спешке, — и в выборку попадают чужие документы, эмбеддинги или история обращений. Мультитенантная архитектура должна опираться на принудительное разделение на уровне хранилища и доступа, а не на внимательность разработчика.
Второе узкое место платформы — общий контур и шумные соседи. Пул инференса, очередь задач, кэш и лимит соединений делятся между всеми: один клиент запускает массовую переиндексацию и поднимает время ответа у остальных. Без квот и приоритетов на тенанта, а также без метрик в разрезе клиента, причина находится только перебором.
Дальше расползаются конфигурации: у части клиентов свои модели и промпты, у части — региональные требования к хранению данных. Настройки живут одновременно в коде, в переменных окружения и в ручных правках базы, поэтому откат релиза перестаёт быть предсказуемым, а время реакции на инцидент растёт вместе с числом исключений.
Масштабировать такую платформу можно только пересборкой модели изоляции. Разбираем, как это закрывается — от схемы разделения тенантов до квот, конфигурации как данных и наблюдаемости по каждому клиенту.
Что даёт платформа: изоляция, скорость и предсказуемость
Мультитенантность убирает целый класс отказов, который обычно всплывает уже в проде: запрос одного клиента получает доступ к чужим данным. Мы разводим данные, ключи шифрования и очереди по клиентам, а доступ ограничиваем политикой на уровне самого хранилища — пересечение становится невозможным по конструкции, а не по аккуратности разработчика. Саму проверку изоляции держим в автотестах, которые гоняются на каждом изменении прав доступа.
Под нагрузкой платформа деградирует управляемо. У каждого клиента свои лимиты и приоритет в очередях, поэтому тяжёлый пересчёт у одного не забирает ресурсы у остальных: падает скорость обработки, но не теряются данные и не рвутся интеграции. По метрикам видно, какой контур упирается в потолок, и его поднимают отдельно, не трогая соседей, — вместо общего падения получается ограниченное замедление у одного клиента.
Подключение нового клиента — это конфигурация контура, а не отдельное развёртывание: изоляция, лимиты, роли и шифрование включаются шаблоном. Первые рабочие сценарии у клиента появляются в тот же день, а не через недели согласований, и сразу с тем же набором гарантий, что у остальных.
Восстановление тоже привязано к клиенту: откат по одному не затрагивает прочих, а возврат в работу измеряется минутами. Простой перестаёт быть общим событием — мы ограничиваем его долей затронутых клиентов и числом ручных операций, которые приходится делать инженеру.
Режимы разделения клиентов: общий контур, пулы, отдельные среды
Мультитенантность AI SaaS — это не только про то, где хранятся данные клиентов, но и про то, как делятся вычислительные ресурсы моделей, квоты и очереди запросов. Режим разделения задаёт, насколько пиковая нагрузка одного клиента задевает остальных и какие требования по изоляции мы можем подтвердить документально.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Общий контур | Много клиентов с похожими сценариями, невысокая чувствительность данных, важна скорость вывода новых возможностей | Нет физической изоляции: активный клиент поднимает время ответа у соседей; разделение данных держится только на логике приложения |
| Пул клиентов | Группы со схожими требованиями: отрасль, регион, уровень чувствительности | Внутри пула ресурсы общие — нужны раздельные квоты и маршрутизация запросов по пулу |
| Выделенная среда | Крупный клиент или данные с особыми требованиями к хранению и доступам | Больше инженерного времени на сопровождение и обновления, ниже плотность использования ресурсов, длиннее цикл релиза |
| Гибридная схема | Основная масса клиентов в общем контуре, чувствительная часть — отдельно | Две схемы в эксплуатации: нужен общий слой управления доступами, версиями моделей и переносом данных между средами |
Выбор не бинарный: сначала смотрим на чувствительность данных, профиль нагрузки и требования к обновлениям, и только потом — на режим разделения. Переключение между вариантами — это изменение конфигурации и перенос данных, а не переписывание продукта.
Этапы внедрения: от аудита контура до передачи регламентов
Работы идут последовательно, и каждый этап опирается на артефакты предыдущего: к настройке изоляции мы не переходим, пока не зафиксированы границы данных и владельцы сущностей. Порядок одинаков и для нового контура, и для платформы, которая уже обслуживает заказчиков — различается только объём миграции.
-
Аудит контура. Разбираем текущую схему, источники данных, интеграции и точки, где данные разных заказчиков могут пересечься. На выходе — карта потоков и перечень сущностей с привязкой к тенанту.
-
Модель тенантов. Выбираем уровень изоляции: раздельные схемы и ключи шифрования на заказчика, общие таблицы с правилами доступа по строке или гибрид. Решение фиксируется в схеме данных и позже почти не пересматривается.
-
Настройка изоляции. Закрываем разграничение доступа на уровне запросов, отдельные хранилища для чувствительных данных, квоты на вычисления и лимиты одновременных задач. Отдельно гасим шумных соседей: тяжёлая задача одного заказчика не должна менять отклик для остальных.
-
Проверка под нагрузкой. Прогоняем сценарии с несколькими активными заказчиками: пиковые запросы, длинные операции, деградация. Смотрим, держатся ли квоты и не протекают ли данные между тенантами, снимаем телеметрию по каждому контуру отдельно.
-
Приёмка и передача. Отдаём схему изоляции, настройки, перечень проверок и порядок подключения нового заказчика. Добавляем инструкцию для дежурной смены: как отозвать доступ, как вынести данные по требованию, куда смотреть при инциденте.
Артефакты, которые остаются у заказчика после работ
Комплект документации — не приложение к релизу, а часть результата. Платформа, которую нельзя передать другой команде, остаётся привязанной к нам, поэтому каждое решение мы описываем так, чтобы инженер заказчика повторил его сам: развернул окружение, подключил нового клиента, разобрал инцидент ночью без звонка подрядчику.
- Схемы развёртывания — топология сервисов, точки отказа, схема сети и маршрутизации, порядок подъёма окружения с нуля и восстановления из резервной копии.
- Конфигурации окружений — параметры разработки, предпродакшена и продакшена в едином виде, список внешних зависимостей и переменных, правила их изменения через систему контроля версий.
- Политики доступа — роли и права, принцип изоляции данных арендаторов, разграничение доступа инженеров к клиентским данным, порядок выдачи и отзыва доступов.
- Регламент подключения клиента — пошаговый чек-лист от заявки до продакшена: создание арендатора, настройка лимитов, подключение источников данных, проверка перед запуском.
- Регламент вывода клиента — выгрузка данных в открытых форматах, сроки хранения, порядок удаления арендатора без влияния на остальных.
- Инструкции для дежурной смены — перечень типовых отказов, что смотреть в первую очередь, какие действия безопасны, а какие требуют согласования, и когда эскалировать.
- Журнал инженерных решений — почему выбраны такие схемы изоляции и хранения, какие альтернативы отклонили и при каких условиях стоит вернуться к вопросу.
Каждый документ привязан к реальной процедуре: его проверяют на учебном подключении арендатора до передачи. Если по инструкции не получается пройти путь без нас — дорабатываем не текст, а саму процедуру.
Кейс: как убрали пересечения данных между клиентами
Что было
Платформа работала на общем контуре: одна база, общие таблицы, принадлежность строки клиенту — обычная колонка с идентификатором. Фильтр по ней добавлял каждый обработчик сам, и изоляция держалась на дисциплине разработчиков: на десятках запросов это сходило с рук, на сотнях нашлись места, где условие забыли. У крупного клиента в выгрузке появились строки другой организации — разбор занял несколько дней, потому что воспроизвести сценарий на тестовых данных не получалось.
Второй сбой был не про доступ, а про ресурсы. Тяжёлый отчёт одного клиента занимал общий пул, и у остальных росло время ответа: доля запросов дольше секунды в пиковые часы поднималась с единиц процентов до трети. В поддержке жалобы шли одной очередью, без привязки к клиенту, и инциденты разбирали вслепую.
Что изменили
Изоляцию разделили на два уровня. Доступ к данным перевели на принудительные правила на стороне СУБД PostgreSQL: политика применяется к любому запросу, независимо от того, помнит о ней код или нет, — обойти её забытым условием нельзя. Для чувствительных наборов завели отдельную схему на клиента и закрыли прямой доступ мимо слоя проверки прав.
Вычисления развели по пулам: у каждого клиента квота на параллельные тяжёлые задачи, отчёты и обучение моделей идут отдельной очередью и не вытесняют оперативные запросы. В регрессию добавили проверки изоляции — на каждый новый обработчик прогоняется сценарий «запрос в контексте одного клиента не возвращает строки другого» плюс общий прогон по всем путям доступа.
Случаев видимости чужих данных — ноль за весь период наблюдения, а доля запросов дольше секунды вернулась к единицам процентов при том же пиковом клиенте. Онборд нового клиента сократился с недель до дня: схема и правила доступа поднимаются автоматически, а не правятся вручную в общих таблицах.
Чем мультитенантная изоляция данных отличается от отдельных контуров?
Граница тенанта проходит не по железу, а по тому, где заканчивается один набор прав и начинается другой. Код платформы общий, данные, ключи шифрования и журналы доступа — раздельные. От уровня этой границы зависят стоимость аренды, скорость обновлений и радиус поражения при инциденте.
Логическая изоляция — общий контур, где каждая запись помечена идентификатором тенанта, а доступ ограничен политиками на уровне строк, как в PostgreSQL. Обновление ядра выкатывается один раз для всех, новый клиент заводится за минуты. Цена — ошибка в политике доступа превращается в утечку между клиентами.
Физическая изоляция — отдельная база или контур на клиента. Требования регуляторов закрываются проще, обновление и откат делаются для одного тенанта, не задевая остальных. Обратная сторона — эксплуатация умножается: столько же контуров, копий и настроек, между которыми копится расхождение.
На практике мультитенантность не сводят к «или-или»: клиентов с типовыми требованиями держат в общем контуре, а кому нужен выделенный — выносят отдельно, и изоляция становится свойством тарифа. Критерии — требования к хранению, объём общих справочных данных, нужен ли тенанту свой темп обновлений.
Для сопровождения разница принципиальная. В общем контуре одно исправление закрывает инцидент у всех, но и сбой виден всем сразу. В выделенных контурах сбой остаётся внутри одного клиента, зато обновление приходится проводить отдельно для каждого. Поэтому границу тенанта закладывают в модель данных на старте.
Частые технические сомнения перед стартом работ
Сомнения перед стартом редко бывают про идею — чаще про риск сломать работающее. Отвечаем на вопросы, которые звучат чаще всего.
Можно ли перевести работающую систему без остановки сервиса?
Да. Изоляцию вводят слоями: арендатор определяется по подписке, запрос получает обязательный фильтр, ограничения закрепляются в хранилище — в PostgreSQL это политики доступа к строкам. Схемы расширяются без блокировки, трафик переключается по отдельным клиентам, поэтому остановка нужна только для операций, затрагивающих всех арендаторов сразу.
Как убедиться, что данные клиента недоступны другим?
Проверка автоматическая, а не по обещанию: на каждый маршрут пишется тест, который обращается от имени одного арендатора и ждёт пустой ответ или отказ. Такие тесты входят в сборку, поэтому новая функция не попадёт в продукт, не пройдя проверку изоляции.
Что будет при росте числа клиентов?
Ресурсы распределяются по арендаторам: тяжёлые задачи уходят в очереди, доля мощности на клиента ограничивается, хранилище делится по группам. Один крупный клиент не займёт общий пул и не замедлит остальных.
Кто отвечает за обновления после передачи?
Вы получаете схему развёртывания, регламент обновлений, набор тестов и инструкции для дежурной смены. Первые релизы выпускаются вместе с вашей командой, дальше она ведёт их сама; поддержка на нашей стороне фиксируется отдельным договором.
Обсудим задачу: что подготовить к разговору
Чтобы вернуться с оценкой и планом работ, а не с общими соображениями, нужен минимум вводных по платформе. То, что ниже, обычно снимает половину вопросов на первом же разговоре: мы сразу видим масштаб мультитенантности, узкие места текущей схемы развёртывания и то, где изоляция данных клиентов уже работает, а где держится на договорённостях.
Список не обязательно закрывать целиком — если чего-то под рукой нет, опишите словами, картину восстановим по ходу обсуждения задачи.
- Модель арендаторов. Сколько B2B-клиентов сейчас, какой рост ожидаете, есть ли заказчики с отдельными требованиями к изоляции и размещению данных.
- Текущая схема развёртывания. Общий контур или отдельный экземпляр на клиента, где живут база, кэш, очередь сообщений и хранилище артефактов.
- Границы изоляции. Что уже разделено по арендатору — данные, ключи шифрования, лимиты потребления, журналы — а что пока общее для всех.
- Ограничения и требования. Регуляторные рамки, правила размещения данных, соглашения об уровне сервиса, пиковые и суточные нагрузки.
- Точки интеграции. Какие внешние системы и модели платформа вызывает и с какой задержкой они обязаны отвечать.
- Администрирование. Как сегодня подключают и отключают клиента: внутренняя панель, ручные операции или скрипты.
- Цели ближайшего этапа. Что болит сильнее — стоимость эксплуатации, скорость подключения нового клиента или устойчивость под нагрузкой.
Дальше работаем просто: обсуждаем задачу, фиксируем ограничения и возвращаемся с оценкой и планом работ — по этапам, с критериями приёмки на каждом.







