3

WebTech

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

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

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

Один код на сотни клиентов с изоляцией данных

Проектируем мультитенантный SaaS: выбираем модель изоляции под нагрузку и требования, настраиваем шардирование, tenant-aware кэш и очереди, прогоняем миграции по всем тенантам и автоматизируем онбординг.

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

1
кодовая база и релиз для всех тенантов
schema
общая база, схема или база на тенанта
p95
латентность под шумным соседом
0
ручных операций при онбординге
Задачи

Где ломается мультитенантность

Типовые проблемы SaaS-команд, которые добавили tenant_id в таблицы, но не довели изоляцию до конца.

Модель изоляции выбрана наугад

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

Запрос без tenant_id отдаёт чужие данные

Один забытый фильтр в отчёте, экспорте или админке — и клиент видит строки другого тенанта. В коде такой баг не виден.

Один тенант съедает все ресурсы

«Шумный сосед» выкачивает соединения, CPU и Redis, и деградация чувствуется у всех остальных клиентов сразу.

Кэш и очереди не знают про тенанта

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

Миграции применяются выборочно

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

Оффбординг никто не предусмотрел

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

Решения

Что входит в мультитенантную архитектуру

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

Модели изоляции и их выбор

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

  • Общая база и tenant_id в составных индексах
  • Схема на тенанта: права на схему, копия и DROP по клиенту
  • База или кластер на тенанта для крупных заказчиков
  • Развилка: цена эксплуатации против жёсткости границы

Шардирование по тенантам

Раскладываем тенантов по шардам и маршрутизируем запросы без правок в продуктовом коде.

  • Каталог тенантов и карта tenant → шард
  • Диапазоны ключей и consistent hashing
  • Отдельные пулы соединений и реплики на шард
  • Перенос тенанта между шардами без простоя

Tenant-aware кэш и очереди

Контекст тенанта передаётся во все слои: от ключа в Redis до payload фоновой задачи.

  • Префикс ключей и инвалидация по тегу тенанта
  • Разделение очередей и приоритеты обработки
  • tenant_id в payload задачи и восстановление контекста
  • Защита от подмены ключа и cross-tenant попаданий

Миграции, лимиты, онбординг

Эксплуатация сотен тенантов автоматизируется: обновления, квоты, выдача и закрытие аккаунта.

  • Идемпотентный раннер миграций по всем схемам и базам
  • Отчёт о версии схемы по каждому тенанту
  • Квоты и rate limit на тенанта в Redis
  • Провижининг, выгрузка и удаление данных тенанта
Процесс

Как мы строим мультитенантность

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

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

    Аудит и выбор модели изоляции

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

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

    Проектирование маршрутизации

    Проектируем каталог тенантов, карту шардов, tenant-контекст, схемы ключей кэша и очередей, порядок провижининга.

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

    Внедрение и перенос тенантов

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

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

    Нагрузка и запуск

    Проверяем поведение под шумным соседом, настраиваем мониторинг по тенантам, отрабатываем онбординг и оффбординг.

Три модели изоляции тенантов и критерии выбора

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

Схема на тенанта (в PostgreSQL — отдельная schema и search_path) даёт более жёсткую границу: права выдаются на схему, резервная копия делается по клиенту, а закрытие аккаунта сводится к удалению схемы. Цена — тысячи объектов в каталоге и миграции, которые нужно применить ко всем схемам согласованно.

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

Шумный сосед, квоты и миграции на масштабе

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

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

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

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

Ориентируемся на требования клиентов и профиль нагрузки. Для тысяч небольших аккаунтов и быстрого запуска подходит общая база с tenant_id и обязательным tenant-контекстом. Когда нужны раздельные права, бэкапы и быстрое удаление по клиенту, берём схему на тенанта. Отдельная база или кластер оправдана для крупных корпоративных заказчиков с требованиями к производительности и локализации данных.

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

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

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

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

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

Спроектируем мультитенантность под ваш рост

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