Изоляция тенантов и лимиты
Изоляция тенантов и лимиты — это фундамент мульти-тенантной архитектуры. Цель: чтобы действия одного арендатора никогда не влияли на данные, безопасность и SLO другого, а ресурсы распределялись справедливо и предсказуемо. Ниже — практичная карта решений от уровня данных до планирования вычислений и инцидент-менеджмента.
1) Модель угроз и цели
Угрозы
Утечка данных между арендаторами (логическая/по кэшу/через логи).
«Noisy neighbor»: деградация производительности из-за всплесков у одного клиента.
Эскалация привилегий (ошибка в политике доступа).
Биллинг-дрифт (несоответствие использования и начислений).
Каскадные отказоустойчивые сценарии (инцидент одного приводит к даунтайму многих).
Цели
Строгая изоляция данных и секретов.
Пер-тенантные лимиты/квоты и справедливое планирование.
Прозрачный аудит, наблюдаемость и биллинг.
Локализация инцидентов и быстрое восстановление per tenant.
2) Уровни изоляции (сквозная модель)
1. Данные
`tenant_id` в ключах и индексах, Row-Level Security (RLS).
Шифрование: иерархия KMS → ключ арендатора (KEK) → ключи данных (DEK).
Раздельные схемы/БД при высоких требованиях (Silo), общий кластер c RLS для эффективности (Pool).
Политики ретеншна и «право на забывание» per tenant, crypto-shredding ключей.
2. Вычисления
Квоты CPU/RAM/IO, пулы воркеров на тенанта, «взвешенные» очереди.
Изоляция GC/heap (контейнеры/настройки JVM/Runtime), лимиты на parallelism.
Пер-тенантный autoscaling + backpressure.
3. Сеть
Сегментация: private endpoints/VPC, ACL по `tenant_id`.
Rate limiting и per-tenant connection caps на границе.
Защита от DDoS/ботов с учетом плана/приоритета.
4. Операции и процессы
Поарендаторные миграции, бэкапы, DR, feature-flags.
Инциденты — «микро-бласт-радиус»: фьюзинг по `tenant_id`.
3) Контроль доступа и контекст арендатора
AuthN: OIDC/SAML; токены несут `tenant_id`, `org_id`, `plan`, `scopes`.
AuthZ: RBAC/ABAC (роли + атрибуты проекта, отдела, региона).
Контекст на границе: API-шлюз извлекает и валидирует контекст тенанта, дополняет лимитами/квотами, пишет в трейсы.
Принцип «двойного замка»: проверка в сервисе + RLS/политики БД.
4) Данные: схемы, кэш, логи
Схемы:- Shared-schema (row-level): максимум эффективности, строгий RLS обязателен.
- Per-schema: компромисс изоляции/операбельности.
- Per-DB/cluster (Silo): для VIP/регулируемых.
Кэш: префиксы ключей `tenant:{id}:…`, TTL по планам, защита от cache-stampede (lock/early refresh).
Логи/метаданные: полная псевдонимизация PII, фильтры по `tenant_id`, запрет «склейки» логов разных арендаторов.
5) Лимитирование трафика и операций
Базовые механики
Token Bucket: сглаженные всплески, параметризация `rate`/`burst`.
Leaky Bucket: стабилизация throughput.
Fixed Window / Sliding Window: простые/точные квоты по окну времени.
Concurrency limits: caps на одновременные запросы/джобы.
Где применять
На границе (L7/API-шлюз) — основная защита и «быстрый отказ».
В сердцевине (в сервисах/очередях) — для второго контура и «fair share».
Политики
По тенанту/плану/эндпойнту/типу операции (публичные API, тяжелые экспорты, админ-действия).
Priority-aware: VIP получает больший `burst` и вес при арбитраже.
Idempotency-keys для безопасных ретраев.
Пример профилей (понятия)
Starter: 50 req/s, burst 100, 2 параллельных экспорта.
Business: 200 req/s, burst 400, 5 экспортов.
Enterprise/VIP: 1000 req/s, burst 2000, выделенные воркеры.
6) Квоты и справедливое планирование (fairness)
Квоты по ресурсам: хранилище, объекты, сообщения/мин, задания/час, размер очередей.
Weighted Fair Queuing / Deficit Round Robin: «взвешенный» доступ к общим воркерам.
Per-tenant worker pools: жесткая изоляция для шумных/критичных клиентов.
Admission control: отказ/деградация до выполнения, когда квоты исчерпаны.
Backoff + jitter: экспоненциальные задержки, чтобы не синхронизировать всплески.
7) Наблюдаемость и биллинг per tenant
Обязательные теги: `tenant_id`, `plan`, `region`, `endpoint`, `status`.
SLI/SLO per tenant: p95/p99 latency, error rate, availability, utilization, saturation.
Usage-метрики: счетчики по операциям/байтам/секундам CPU → агрегатор → инвойсы.
Идемпотентность биллинга: снапшоты на границе, защита от двойных списаний/потери событий.
Дашборды сегментами: VIP/регулируемые/новые арендаторы.
8) Инциденты, деградация и DR «по арендаторам»
Фьюзинг по `tenant_id`: аварийное отключение/троттлинг конкретного арендатора без влияния на остальных.
Graceful Degradation: read-only режим, очереди в «песочницу», отложенные задачи.
RTO/RPO per tenant: целевые значения восстановления и потерь для каждого плана.
Учения: регулярные «game days» с отключением шумного арендатора и проверкой DR.
9) Соответствие требованиям (residency, приватность)
Пинning тенанта к региону; четкие правила кросс-региональных потоков.
Аудит доступа к ключам/данным, журналирование админ-операций.
Управление ретеншном и экспортом данных per tenant.
10) Мини-референс: как собрать вместе
Поток запроса
1. Edge (API-шлюз): TLS → извлечь `tenant_id` → валидация токена → применить rate/quotas → проставить трейсы.
2. Полиси-движок: контекст `tenant_id/plan/features` → решение о маршруте и лимитах.
3. Сервис: проверка прав + метки `tenant_id` → работа с БД под RLS → кэш с префиксом.
4. Usage-сбор: счетчики операций/байтов → агрегатор → биллинг.
Данные
Схема/БД по стратегии (row-level/per-schema/per-DB).
KMS: ключи на арендатора, ротация, crypto-shredding при удалении.
Вычисления
Очереди с весами, пулы воркеров per tenant, caps по concurrency.
Autoscaling по пер-тенантным метрикам.
11) Псевдо-политики (для ориентации)
yaml limits:
starter:
req_per_sec: 50 burst: 100 concurrency: 20 exports_parallel: 2 business:
req_per_sec: 200 burst: 400 concurrency: 100 exports_parallel: 5 enterprise:
req_per_sec: 1000 burst: 2000 concurrency: 500 exports_parallel: 20
quotas:
objects_max: { starter: 1_000_000, business: 20_000_000, enterprise: 100_000_000 }
storage_gb: { starter: 100, business: 1000, enterprise: 10000 }
12) Чек-лист перед продом
- Единый источник истины `tenant_id`; везде прокидывается и логируется.
- Включен RLS/ACL на уровне БД + сервисная проверка (двойной замок).
- Ключи шифрования per tenant, документирована ротация/удаление (crypto-shredding).
- Лимиты/квоты на границе и внутри; протестированы всплески и «burst».
- Fair-queuing и/или выделенные воркеры для VIP; caps на concurrency.
- Пер-тенантные SLO и алерты; дашборды по сегментам.
- Usage-сбор идемпотентен; сведение с биллингом проверено.
- DR/инциденты локализуются до арендатора; фьюзинг по `tenant_id` отрабатывает.
- Кэш/логи разделены по арендаторам; PII маскирована.
- Процедуры миграций/бэкапов/экспорта — поарендаторные.
13) Типичные ошибки
RLS отключен/обойден «служебным» пользователем — риск утечки.
Единый глобальный лимитер → «noisy neighbor» и нарушение SLO.
Общие кэши/очереди без префиксов → пересечение данных.
Биллинг считает по логам, которые теряются при пиках.
Отсутствие поарендаторного фьюзинга — каскадные падения.
Миграции «одним махом» без возможности стопнуть проблемный `tenant_id`.
14) Быстрый выбор стратегии
Регулируемые/VIP: Silo-данные (per-DB), выделенные воркеры, строгие квоты и residency.
Массовый SaaS: Shared-schema + RLS, сильные лимиты на границе, fair-queuing внутри.
Нагрузка «шумная/пульсирующая»: большие `burst` + жесткие concurrency-caps, backpressure и приоритеты по планам.
Заключение
Изоляция тенантов и лимиты — это про границы и справедливость. Четкий `tenant_id` сквозь стек, RLS и шифрование на данных, лимитирование и квоты на границе и в сердцевине, справедливый планировщик, наблюдаемость и локализация инцидентов — все это вместе дает безопасность, предсказуемое качество и прозрачный биллинг для каждого арендатора, даже при агрессивном росте платформы.