Мульти-тенантное ядро
Мульти-тенантное ядро — это базовый слой платформы/продукта, который обслуживает множество независимых клиентов (тенантов) на общих ресурсах при гарантированной изоляции, управляемых лимитах и безопасной кастомизации. Хорошо спроектированное ядро снижает TCO, ускоряет онбординг, упрощает релизы и обеспечивает предсказуемое качество для каждого арендатора.
1) Модель арендатора и границы изоляции
Определения
Тенант (Tenant/Org/Account): логическая организация с собственными пользователями, данными, политиками и лимитами.
Изоляция: способность предотвращать влияние одного арендатора на данные, производительность и безопасность другого.
Уровни изоляции
1. Данные: отдельные БД/схемы/таблицы, шифрование «ключом арендатора», фильтры `tenant_id`.
2. Вычисления: квоты CPU/RAM/IO, пул воркеров на тенанта или «взвешенные» очереди.
3. Сеть: сегментация, приватные endpoints/VPN, списки разрешений по арендаторам.
4. Операции: миграции, бэкапы, DR и инциденты с границами воздействия «на одного арендатора».
Паттерны многотенантности
Silo (жесткая изоляция): отдельные кластеры/БД на тенанта. Максимальная безопасность, высокая цена.
Pool (общие ресурсы): общая инфраструктура с логической изоляцией; лучшая эффективность, выше риск «noisy neighbor».
Bridge/Hybrid: гибрид — общая плоскость управления + выборочно «silo» для VIP/регулируемых клиентов.
2) Идентификация и маршрутизация арендаторских запросов
Разрешение арендатора (Tenant Resolution)
По домену: `https://{tenant}.example.com`
По пути: `/t/{tenant}/…`
По заголовку: `X-Tenant-Id`, `X-Org` (проверка подписи)
По токену: клеймы `tenant_id`, `org_id`, `plan`, `scopes`
Маршрутизация
L7-шлюз (API-шлюз/Ingress) извлекает `tenant_id`, обогащает контекст (`plan`, лимиты, регион), записывает в трейсы/логи.
Функциональные сервисы принимают контекст «только для чтения»; решения по маршруту и лимитам принимает гейтвей/полиси-движок.
3) Данные и схемы: стратегии
Варианты хранения
Shared-schema, row-level: один набор таблиц, поле `tenant_id`, строгие RLS (Row-Level Security).
Shared-DB, per-schema: одна СУБД, отдельная схема на тенанта; баланс между управляемостью и изоляцией.
Per-DB/cluster: отдельная БД/кластер на тенанта; дороже, проще для суверенных требований.
Ключевые практики
Везде явно передавать `tenant_id` и включать его в составные ключи/индексы.
RLS/политики доступа на уровне СУБД + сервисная валидация «двойным замком».
Шифрование: иерархия ключей (root KMS → key-envelope на тенанта → DEK на объект).
Архив/ретеншн и «право на забвение» управляются политиками на уровне арендатора.
4) Настройки, фичи и версии
Конфигурации по тенанту
Таблица/хранилище `tenant_config` (план, квоты, фича-флаги, локализация, SLA).
Приоритеты конфигов: дефолт → план → тенант → окружение → пользователь.
Кеширование конфигов с коротким TTL и инвалидацией по событию.
Фича-флаги и совместимость
Включение функций точечно (per-tenant/per-cohort), канареечные раскатки.
Версионирование API: стабильный контракт + адаптеры на границе (back/forward-compatible форматы).
5) Лимиты, квоты и биллинг
Политики потребления
Rate limiting: `requests/sec` per tenant/route, «токен-бакет» с приоритетами планов.
Quotas: объем хранилища, количество объектов, сообщений/мин, jobs/час.
Fairness: «взвешенное расписание» очередей + изоляция воркеров для VIP.
Биллинг
Счетчики по `tenant_id` (usage-метрики) → агрегаторы → инвойс.
Снапшоты usage на границе (идемпотентность и защита от потери событий).
Модели: фиксированный план + переп consumption, пост-пей/пре-пей, скидки «tiered».
6) Безопасность и доступ
Аутентификация/авторизация
OIDC/SAML с клеймами `tenant_id`, `roles`, `scopes`.
RBAC/ABAC: роли на уровне арендатора (Owner/Admin/Reader), атрибуты проекта/отдела.
Делегированный доступ (service-to-service) с mTLS и ограниченными токенами.
Границы доверия
Политики принятия запросов: проверка подписи заголовков, nonce/timestamp, привязка к источнику.
Секреты и ключи: ротация per-tenant, отдельные KMS-контексты, аудит ключевых операций.
Multi-region & data residency: пинning тенанта к региону, контролируемые кросс-региональные потоки.
7) Наблюдаемость «по арендаторам»
Трассировка и метрики
Обязательные теги: `tenant_id`, `plan`, `region`, `endpoint`, `status`.
SLI/SLO per tenant: `availability`, `p95 latency`, `error budget`.
Дашборды и алерты по сегментам (VIP/регулируемые/новые).
Логи и аудит
Журналы действий (кто/что/когда/где) с неизменяемым хранилищем и ретеншном по политике арендатора.
Пред-агрегация событий для дешевого хранения, восстановление детализации «по клику».
8) Производительность и «noisy neighbor»
Анти-шумовые меры
Лимиты на уровень очередей/воркеров, CPU-shares и IO-пропорции per tenant.
Разделение кэшей: префиксы ключей `tenant:{id}:…`, TTL по планам, защита от «cache stampede».
Индексы и планы запросов с учетом селективности по `tenant_id`.
Холодные старты и «теплые» пулы
Пред-прогрев для VIP/пиковых окон.
Эластичные пулы воркеров по сигналам метрик (backpressure/автоскейлинг).
9) Обновления и миграции без простоя
Стратегия
Backward-совместимые миграции (expand → migrate → contract).
Миграции «по арендаторам»: батчи с контролем прогресса, «пауза/откат» для конкретного `tenant_id`.
Семплирование и «канареечные» миграции на подмножестве арендаторов.
DR и инциденты
DR-план с RTO/RPO per tenant; частичный «read-only режим» без глобального даунтайма.
Изоляция инцидента: фьюзинг по `tenant_id`, тушение «горячего» арендатора не затрагивает остальных.
10) API и протоколы
REST/gRPC с обязательным контекстом арендатора (в клеймах/заголовках).
События (event-driven): топики с неймингом `tenant.{id}.event`, фильтры и ACL на подписки.
Глобальные точки входа: L7-шлюз валидирует контекст, применяет лимиты, шифрует PII по политике тенанта.
11) Жизненный цикл арендатора
1. Провижининг: создание записи арендатора, генерация ключей/конфигов, привязка региона.
2. Активация: выпуск клиента OIDC/SAML, создание ролей/политик, первичных квот.
3. Эксплуатация: мониторинг, биллинг, обновления флагов/планов.
4. Суспенд/троттлинг: заморозка с сохранением данных/экспорта.
5. Удаление/экспорт: ретеншн, законсервированные бэкапы, крипто-стирание ключей (crypto-shredding).
12) Мини-эталон архитектуры (словесная схема)
Edge (API-шлюз): TLS/mTLS, извлечение `tenant_id`, лимиты, аудит.
Control Plane: каталог арендаторов, конфиги, фича-флаги, биллинг, политики.
Data Plane (сервисы): stateless-сервисы, очереди, воркеры с квотами; Redis/kv с префиксами по тенанту.
Storage: RLS-БД/отдельные схемы/БД; KMS с ключами на арендатора; объектное хранилище c envelope-шифрованием.
Observability: трейсинг/метрики/логи с тегом `tenant_id`, алерты per plan.
Admin: изолированные операции (миграции/бэкапы) на подмножестве арендаторов.
13) Контрольный список перед продом
- Единый способ определения `tenant_id` на границе и в сервисах.
- Политики RLS/ACL проверены тестами и «негативными сценариями».
- Квоты/лимиты/биллинг валидируются на реальных нагрузках; есть защита от «биллинг-дропов».
- Наблюдаемость и SLO per tenant; алерты для VIP/регулируемых.
- Миграции совместимы, есть частичный откат и поарендаторные батчи.
- DR-сценарии с RTO/RPO per tenant и регулярные учения.
- Шифрование «ключом арендатора», ротация и аудит ключей.
- Документация контрактов API/событий и политики версионирования.
14) Типичные ошибки
Глобальные миграции «одним махом» без возможности остановить на проблемном арендаторе.
Скрытая зависимость от `tenant_id` в кэше/очередях → утечки данных/пересечения очередей.
Смешение контекстов (admin-операции случайно без `tenant_id`).
Отсутствие «двойного замка»: только сервисная проверка без RLS в БД.
Единый лимитер на весь кластер → «noisy neighbor» и нарушение SLO.
Непрозрачный биллинг без идемпотентности и аудит-трейла.
15) Быстрый выбор стратегии
Строгая изоляция/регулирование: Silo (отдельные БД/кластера), регион-лок.
Сбалансированная эффективность: Shared-DB per schema + RLS, ключи per tenant.
Высокий real-time трафик: общие очереди с «взвешенными» квотами и выделенными воркерами для VIP.
Много кастомизаций: фича-флаги + адаптеры API, хранение конфигов по приоритетам.
Заключение
Мульти-тенантное ядро — это дисциплина инженерных границ: явное определение `tenant_id`, строгая изоляция на всех слоях, управляемые квоты и прозрачный биллинг, плюс наблюдаемость и совместимость релизов. Следование описанным паттернам позволяет масштабировать продукт, не жертвуя безопасностью, качеством и скоростью изменений для каждого арендатора.