Модель изоляции выбрана наугад
Команда берёт общую базу с tenant_id по умолчанию, а потом упирается в требования корпоративных клиентов и в рост каталога таблиц.
Выберите тему — соберём контекст
Проектируем мультитенантный SaaS: выбираем модель изоляции под нагрузку и требования, настраиваем шардирование, tenant-aware кэш и очереди, прогоняем миграции по всем тенантам и автоматизируем онбординг.
Или сразу: +7 (962) 368-39-51 Telegram
Типовые проблемы SaaS-команд, которые добавили tenant_id в таблицы, но не довели изоляцию до конца.
Команда берёт общую базу с tenant_id по умолчанию, а потом упирается в требования корпоративных клиентов и в рост каталога таблиц.
Один забытый фильтр в отчёте, экспорте или админке — и клиент видит строки другого тенанта. В коде такой баг не виден.
«Шумный сосед» выкачивает соединения, CPU и Redis, и деградация чувствуется у всех остальных клиентов сразу.
Ключи кэша без префикса тенанта и общая очередь задач приводят к тому, что фоновая обработка читает чужой контекст.
Из тысячи схем обновили 999: один тенант живёт на старой версии схемы, и ошибка всплывает только у него.
Клиент уходит, а его данные остаются в десятке таблиц, в бэкапах и в поисковом индексе: выгрузка и удаление делаются вручную.
Изоляция, маршрутизация и эксплуатация тенантов проектируются вместе, иначе на масштабе они начинают мешать друг другу.
Подбираем модель под требования к изоляции, стоимость и профиль нагрузки, а не по привычке.
Раскладываем тенантов по шардам и маршрутизируем запросы без правок в продуктовом коде.
Контекст тенанта передаётся во все слои: от ключа в Redis до payload фоновой задачи.
Эксплуатация сотен тенантов автоматизируется: обновления, квоты, выдача и закрытие аккаунта.
Сначала фиксируем требования к изоляции и профиль нагрузки, потом выбираем модель — переезд между моделями позже стоит дороже.
Смотрим текущую схему данных, нагрузку и требования клиентов, сравниваем три модели изоляции по цене и рискам.
Проектируем каталог тенантов, карту шардов, tenant-контекст, схемы ключей кэша и очередей, порядок провижининга.
Реализуем контекст и маршрутизацию, пишем раннер миграций, переносим существующих клиентов и включаем квоты.
Проверяем поведение под шумным соседом, настраиваем мониторинг по тенантам, отрабатываем онбординг и оффбординг.
Мультитенантность не сводится к колонке tenant_id. Модель выбирают по трём осям: стоимость эксплуатации, жёсткость границы между клиентами и предсказуемость нагрузки. Общая база с tenant_id дешевле всего: одна миграция, один пул соединений, простая статистика по ресурсам. Плата — общие индексы и кэш, а также риск, что запрос без фильтра вернёт чужие строки.
Схема на тенанта (в PostgreSQL — отдельная schema и search_path) даёт более жёсткую границу: права выдаются на схему, резервная копия делается по клиенту, а закрытие аккаунта сводится к удалению схемы. Цена — тысячи объектов в каталоге и миграции, которые нужно применить ко всем схемам согласованно.
Отдельная база или кластер на тенанта — максимальная изоляция и предсказуемая производительность, но это отдельные пулы соединений, свой контур бэкапов и полноценный провижининг.
Самая частая причина деградации мультитенантного сервиса — не изоляция данных, а «шумный сосед». Один тенант с тяжёлым отчётом или ретраями забирает соединения, CPU и память Redis, и это чувствуют все. Поэтому мы относимся к тенанту как к единице квот: ограничения на частоту запросов, на параллельные фоновые задачи, на объём выгрузок и на длительность тяжёлых операций.
Отдельно мы фиксируем контракт тенант-контекста: он передаётся в HTTP-запрос, в задачу очереди и в фоновый планировщик, а не выводится из глобального состояния процесса.
Ориентируемся на требования клиентов и профиль нагрузки. Для тысяч небольших аккаунтов и быстрого запуска подходит общая база с tenant_id и обязательным tenant-контекстом. Когда нужны раздельные права, бэкапы и быстрое удаление по клиенту, берём схему на тенанта. Отдельная база или кластер оправдана для крупных корпоративных заказчиков с требованиями к производительности и локализации данных.
Миграции превращаются в идемпотентный процесс: раннер обходит реестр тенантов, применяет версию к каждому и пишет результат в таблицу статусов. Обход идёт пакетами с ограничением параллелизма, чтобы не положить кластер, а упавший тенант не блокирует остальных. Отдельный отчёт показывает, какие тенанты отстали от текущей версии схемы.
Комбинируем три меры: квоты на тенанта, разделение ресурсов и наблюдаемость. Квоты ограничивают частоту запросов, параллельные фоновые задачи и объём выгрузок. Тяжёлые или крупные тенанты выносятся в отдельные очереди, воркеры и при необходимости на отдельный шард. Метрики разрезаются по tenant_id, чтобы деградация была видна до жалоб клиентов.
Онбординг — это автоматический пайплайн: создание схемы или базы, миграции, выдача прав, генерация ключей, установка квот, первичный бэкап и запись в каталог тенантов. Оффбординг симметричен: выгрузка всех данных тенанта в согласованном формате, удаление из кэша и поискового индекса, удаление схемы или базы и подтверждение очистки резервных копий по политике хранения.
Смежные технические темы, с которыми эта задача обычно решается в одном проекте.
Разберём ваши требования к изоляции и нагрузку, предложим модель и план перехода без остановки сервиса.
Cookie и аналитика
Мы используем необходимые cookie для работы сайта и форм. Аналитические cookie (Яндекс.Метрика, включая запись сессий) подключаем только с вашего согласия — от него можно отказаться. Подробнее: Политика использования cookie и обработка персональных данных.