awesome-everything EN
↑ Обратно к восхождению

Базы данных

Schema-based шардирование и альтернативы мультиарендности

Суть Citus 12 schema-based шардирование, database-per-tenant, маршрутизация на уровне приложения и RLS — четыре валидные архитектуры мультиарендности — каждая с конкретным диапазоном числа клиентов и требований к изоляции.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 12 min

B2B SaaS с 200 корпоративными клиентами требует contractual data isolation — данные каждого клиента никогда не должны смешиваться в одной таблице. Row-based шардирование Citus помещает нескольких клиентов в один физический шард. Продуктовая команда спрашивает: существует ли более строгая модель изоляции, которую может обеспечить Postgres?

Четыре архитектуры мультиарендности

АрхитектураЕдиница изоляцииЧисло клиентовОперационная стоимость
RLS на одном PostgresНа уровне строк (применение политики)Неограниченно до насыщения одного PGНизкая; баги политики молча открывают данные
Citus row-based шардированиеШард (несколько клиентов на шард)Тысячи — десятки тысячСредняя; Citus управляет маршрутизацией
Citus schema-based (12+)Схема (одна на клиента)Несколько тысяч (потолок)Средняя; схема — единица деплоя
Database-per-tenantПолная база данных PostgresДесятки — ~500Высокая; N бэкапов, N обновлений, N пулов

Citus 12 schema-based шардирование

Представленное в июле 2023, Citus 12 добавило schema-based шардирование: каждый клиент получает выделенную схему Postgres, и Citus распределяет схемы по воркерам.

-- Онбординг клиента: создать схему, Citus назначает её воркеру
CREATE SCHEMA acme;
CREATE TABLE acme.orders (id BIGINT, ...);
CREATE TABLE acme.users  (id BIGINT, ...);

-- Приложение: ограничить соединение схемой клиента
SET search_path TO acme, public;
-- Все последующие ссылки на таблицы разрешаются внутри схемы acme
-- Citus прозрачно маршрутизирует на воркер acme

Преимущества над row-based шардированием:

  1. Не требуется общая колонка ключа распределения: любой запрос внутри схемы выполняется на её воркере — joins между любыми таблицами в одной схеме всегда локальные.
  2. Схема — единица деплоя: CREATE SCHEMA для онбординга, DROP SCHEMA CASCADE для оффбординга, перемещение схемы между воркерами для ребалансировки.
  3. Чистая изоляция клиентов: имена таблиц разные для каждой схемы — один клиент не может случайно прочитать данные другого.
  4. Миграции на клиента: ALTER TABLE acme.orders ADD COLUMN ... затрагивает только эту схему.

Ограничения:

  • Потолок числа клиентов: Citus рекомендует меньше нескольких тысяч схем. Метаданные схем загружаются в планировщик при каждом запросе; тысячи схем замедляют планирование.
  • Кросс-клиентские запросы по-прежнему кросс-шардовые: аналитика по нескольким клиентам всё равно требует fan-out.
  • Reference tables неприменимы внутри схем: lookup-таблицы должны быть в каждой схеме или доступны из общей схемы.

Оптимальная зона применения: B2B SaaS с 50–2000 корпоративными клиентами, где требуется contractual или regulatory data isolation.

Маршрутизация на уровне приложения

Полностью обойти Citus: код приложения поддерживает карту шардов (таблицу или сервис, маппящий tenant_id → connection_string) и явно маршрутизирует запросы.

// Пример: слой маршрутизации читает клиента из контекста запроса
const shard = await shardMap.get(req.tenantId);
const db = connectionPool(shard.connectionString);
return db.query('SELECT * FROM orders WHERE ...', [req.tenantId]);

Плюсы: явность, нет дополнительного продукта базы данных, максимальный контроль, логика маршрутизации на клиента (регион, тир тарифного плана). Минусы: каждая кросс-шард задача становится кодом приложения — joins, транзакции, fan-out, ребалансировка, failover. Слой маршрутизации — критическая инфраструктура первого уровня, которой вы теперь владеете.

Часто применяется, когда число шардов невелико (10–100) и запросы строго привязаны к клиентам. При 5000 клиентах со сложными запросами Citus обычно требует меньше инженерных усилий на многолетнем горизонте.

Database-per-tenant

Каждый клиент получает выделенную базу данных Postgres (или инстанс). Максимальная изоляция: клиенты буквально не могут делить никакую инфраструктуру на уровне базы данных.

Операционная модель:

  • PgBouncer пул на (клиент, база данных)
  • Бэкапы на клиентскую базу данных
  • Минорные и мажорные обновления Postgres на клиентскую базу данных
  • Миграции схемы, деплоируемые на клиента (или батчами)

Практический потолок: ~100–500 клиентов, прежде чем операционные накладные расходы начинают доминировать. Ниже этого значения database-per-tenant часто проще, чем Citus для регулируемых отраслей (финансы, здравоохранение), где contractual isolation — жёсткое требование.

Почему это работает

Почему Citus рекомендует меньше нескольких тысяч схем для schema-based шардирования? Планировщик загружает метаданные схем (записи pg_namespace, pg_class) в рабочую память во время планирования. При 10 схемах это пренебрежимо мало. При 10 000 схем каждый план запроса включает обработку тысяч записей пространств имён, добавляя 10–50 мс ко времени планирования — что доминирует над временем выполнения OLTP-запроса. Именно поэтому schema-based шардирование имеет потолок, а row-based шардирование (которое не загружает метаданные на клиента в планировщик) масштабируется до десятков тысяч клиентов.

Викторина

B2B SaaS имеет 200 клиентов, требует contractual data isolation для каждого, а у инженерной команды нет экспертизы по Citus. Какая архитектура подходит лучше всего?

Викторина

Каков главный потолок числа клиентов для schema-based шардирования Citus и почему?

Вспомните перед уходом
  1. 01
    Что добавил Citus 12 (июль 2023) и какую проблему это решает, которую row-based шардирование не решает?
  2. 02
    Для B2B SaaS с 5000 клиентов, где топ-5% генерируют 80% трафика и все запросы несут tenant_id, какая архитектура мультиарендности наиболее вероятно правильная и почему?
  3. 03
    Когда маршрутизация на уровне приложения (пользовательская карта шардов) является правильным выбором вместо Citus?
Итог

На Postgres существуют четыре архитектуры мультиарендности, каждая подходящая для разного числа клиентов и требований к изоляции: RLS на одном Postgres (неограниченное число клиентов, логическая изоляция до достижения мощности), Citus row-based шардирование (тысячи — десятки тысяч, изоляция на уровне шарда), Citus schema-based шардирование (несколько тысяч, структурная изоляция на схему, введена в Citus 12 / июль 2023), и database-per-tenant (десятки — ~500, максимальная изоляция, наибольшая операционная стоимость). Schema-based шардирование устраняет необходимость в общей колонке ключа распределения и обеспечивает чистое пространство имён таблиц на клиента, но потолок накладных расходов планировщика — несколько тысяч схем. Маршрутизация на уровне приложения с пользовательской картой шардов — жизнеспособная альтернатива для небольшого числа шардов с простыми потребностями маршрутизации. Выбор должен соответствовать числу клиентов, требованию к изоляции и операционной зрелости.

Связанные уроки
встречается в140
Продолжить восхождение ↑Онлайн-решардинг, 2PC и операционная стоимость шардирования
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.