Learning Platform
Глоссарий Troubleshooting
Урок 16.05 · 25 мин
Средний
dbt-meshmodel-groupsaccesscross-project-refgovernance

dbt Mesh: введение

dbt Mesh — паттерн governance для больших dbt-проектов, который позволяет разделить один монолитный проект на несколько связанных проектов (per-domain) с контролируемым cross-project ref. Архитектурно это аналог микросервисов для данных: вместо одного монорепо — несколько проектов с явными контрактами.

Полные senior-детали (внутреннее устройство Mesh, performance-tuning, инструменты cross-project lineage) разбираются в dbt III. В этом уроке — концептуальное введение и patterns, которые middle должен понимать.


Проблема, которую решает Mesh

dbt-iii: Mesh архитектура — детальный разбор Data Domains и владение — governance-основание Mesh

Без Mesh большие data-команды живут в монорепо: один dbt-проект, 500+ моделей, все ref’ы внутри. Через год-два роста начинаются проблемы:

  1. Парсинг и компиляция медленные. На 1000+ моделей dbt parse занимает минуту, CI работает 30 минут на любой PR.
  2. Конфликты ownership. Marketing team меняет модель, которой пользуется Finance team. Без явных контрактов — постоянные регрессии.
  3. Большой blast radius. Изменение в stg_users затрагивает 300 downstream моделей. Никто не уверен, что не сломает.
  4. Onboarding cognitive overload. Новый dev открывает проект с 500 моделями в одной папке — теряется.
  5. CI bottleneck. Каждый PR валидирует весь проект, даже если изменение в одной domain-области.

Mesh — это архитектурное решение: разделить монолит на несколько проектов с контрактами. Аналогично transition’у с monolith application на microservices.


Архитектура Mesh

Mesh: типичная архитектура для большой data-команды
dbt_platformCore/platform project: shared sources, staging, common dimensions (dim_date, dim_calendar). Owned by data-platform team. Public access на большинство моделей.
ref('platform', 'dim_date')
dbt_marketingMarketing domain: campaigns, attribution, customer segments. Owned by marketing-analytics team. Mix of private/public.
dbt_financeFinance domain: revenue recognition, expenses, MRR/ARR. Owned by finance team. Most models private.
dbt_productProduct domain: feature usage, retention, A/B tests. Owned by product-analytics team.
cross-project ref только для public моделей
dbt_executive_dashboardExecutive layer: combine metrics из marketing, finance, product. Только consumer — не expose дальше. Все ref'ы из других проектов.

Каждый проект — отдельный git-repo (обычно) с собственным dbt_project.yml. Связь между проектами — через cross-project ref:

-- В dbt_marketing/models/marts/mart_campaign_revenue.sql
SELECT
  c.campaign_id,
  c.campaign_name,
  d.fiscal_quarter
FROM {{ ref('campaigns_attributed') }} AS c
JOIN {{ ref('dbt_platform', 'dim_date') }} AS d
  ON c.day = d.date_day

{{ ref('dbt_platform', 'dim_date') }} — это cross-project ref, который резолвится в production-схему dbt_platform.


Model groups

Model group — это namespace внутри одного проекта, который группирует модели по domain и устанавливает им общий owner и default access.

Декларация группы в _models.yml:

groups:
  - name: marketing_core
    owner:
      name: Marketing Analytics Team
      email: [email protected]

  - name: marketing_internal
    owner:
      name: Marketing Analytics Team
      email: [email protected]

Привязка модели к группе:

models:
  - name: stg_marketing_campaigns
    group: marketing_internal
    access: private
    description: "..."

  - name: mart_campaigns_summary
    group: marketing_core
    access: public
    description: "..."

Зачем groups внутри одного проекта (не только cross-project)?

  1. Ownership clarity. Per-model owner превращается в per-group, реже меняется.
  2. Default access. На уровне группы можно установить default access (private/protected/public) для всех моделей группы.
  3. Foundation для split на проекты. Если у вас в монорепо хорошо организованы groups — split в Mesh-проекты делается легко: вы уже знаете границы domain.

Access levels

access — это аннотация на модели, определяющая, кто может ref’ить эту модель:

AccessКто может refUse case
privateТолько модели той же группы внутри того же проектаInternal staging, helper, intermediate
protectedЛюбая модель того же проекта (default)Любая внутренняя модель проекта
publicЛюбая модель из любого проектаDomain-level marts, public dimensions
models:
  # stg_marketing_campaigns — internal staging, никто кроме marketing не должен ref'ить
  - name: stg_marketing_campaigns
    group: marketing_internal
    access: private

  # mart_campaigns_summary — domain-mart, exposed для cross-project
  - name: mart_campaigns_summary
    group: marketing_core
    access: public

Что enforced и что нет

Важно: access — это enforcement-flag, который dbt проверяет при dbt parse. Если другой проект попытается {{ ref('dbt_marketing', 'stg_marketing_campaigns') }} (где модель private), dbt выдаст ошибку.

Это не просто метаdata — это активный механизм governance.

WARNING

access не защищает от прямого SQL-доступа на warehouse-уровне. Если в Snowflake таблица создаётся с правами на всех, любой пользователь может SELECT * FROM marketing.stg_marketing_campaigns вне dbt. access работает только в dbt-context’е. Реальные warehouse-level grants управляются через grants config (отдельный модуль 11 multi-environment).


Cross-project ref: механика

Когда вы пишете {{ ref('dbt_platform', 'dim_date') }} в проекте dbt_marketing, dbt должен знать:

  1. Какой проект dbt_platform? Где его конфиг?
  2. В какой схеме живёт dim_date в production?
  3. Версия модели — есть ли deprecation_date, какая latest_version?

Эта информация передаётся через dependencies.yml в потребляющем проекте:

# dbt_marketing/dependencies.yml
projects:
  - name: dbt_platform

И через manifest.json от dbt_platform, который Cloud / Studio автоматически делает доступным consuming проектам.

В Core это требует ручного выкладывания manifest.json от dbt_platform в S3, а consuming-проект скачивает его перед dbt parse. В Cloud Mesh это работает “из коробки” — Cloud хранит manifest всех projects и автоматически разрешает cross-project ref.


Governance patterns

Mesh даёт инструменты, но политика — это правила команды.

Public API contracts

Public-модели — это API проекта для других проектов. К ним должны применяться более строгие правила:

  1. Model contracts включены: enforced columns + types + constraints
  2. Versions: model versions с latest_version и deprecation_date
  3. Tests: уровень тестов выше, чем для internal
  4. Documentation: полное описание columns, business meaning

Внутренние модели (private) могут быть менее формальными — это implementation detail группы.

Deprecation workflow

Когда public-модель меняет API (добавили / удалили / переименовали колонку):

  1. Создать новую версию: mart_campaigns_summary v2 в mart_campaigns_summary_v2.sql
  2. Обновить yml: latest_version: 2, versions: [v: 1, deprecation_date: '2026-09-01'], [v: 2]
  3. Уведомить downstream consumers (через Slack, ownership-routing)
  4. Дать window 1-3 месяца на миграцию
  5. После deprecation_date удалить v1

Это аналог API versioning в HTTP-сервисах. Mesh без deprecation_workflow быстро ломается.

Ownership и responsibility

Каждая public-модель имеет явного owner (через group). Owner отвечает за:

  • Поддержку модели (тесты зелёные, freshness ок)
  • Communication с downstream consumers
  • Deprecation announcements
  • On-call для incidents related к модели

Без явного ownership Mesh не работает — public-модели становятся “ничейными”.


Когда переходить на Mesh

Mesh — серьёзная архитектурная decision. Не делайте этого преждевременно.

Признаки, что Mesh нужен

  • Проект >500 моделей. На меньшем размере overhead Mesh (cross-project complexity, deployment coordination) не окупается.
  • 3+ data-команды в компании, каждая со своим domain. Если одна команда — Mesh искусственный.
  • Cross-team conflicts постоянны. Один dev сломал что-то, что важно другой команде, регрессии часто.
  • CI занимает >20 минут на медианный PR. Split на проекты ускоряет CI значительно.
  • Onboarding занимает >1 месяц. Слишком много структуры для нового dev’а.

Признаки, что Mesh преждевременен

  • Менее 200 моделей в проекте. Просто наладьте папки staging/intermediate/marts и groups.
  • 1-2 dev’а на проект. Mesh-overhead больше, чем benefit.
  • Mono-domain analytics. Если все ваши analytics — про один бизнес-процесс, нет естественных domain-границ.
  • CI быстрый. Если Slim CI на state:modified+ уже даёт CI меньше 10 минут — переход на Mesh не даст значительного speedup.

Промежуточный этап: groups внутри монорепо

Хороший foundation перед Mesh — это groups + access внутри одного проекта. Вы декларируете groups, прописываете access (private/protected/public), и устанавливаете governance-правила, но физически проект остаётся одним. Когда боль роста перерастает groups — split в Mesh готов на 80%, потому что границы уже определены.


Cross-project ref: технические нюансы (introductory)

Что middle должен знать

  1. Cross-project ref работает только для public моделей.
  2. Resolves в production-схему target проекта, не в локальную dev-схему.
  3. Defer работает через cross-project: можно работать с upstream dbt_platform в dev, ref’ить prod-таблицы downstream проекта.
  4. Lineage в Explorer показывает связи между проектами. Можно кликом перейти из marketing-модели в platform-upstream.

Что senior должен знать (dbt III)

  • Performance: cross-project parse может быть медленным, если consumer проект ref’ит много public моделей.
  • State management: как координировать deploy между проектами без race-condition.
  • Versioning conflicts: что делать, если consumer ref’ит v1, а producer уже на v2.
  • Local development: как запустить dbt run локально, если ваш проект ref’ит cross-project, а вы не хотите подключаться к prod-warehouse.

Mesh в Core vs Cloud

Mesh частично работает в Core, полностью — в Cloud.

FeatureCoreCloud Enterprise
Model groupsДа, в _models.ymlДа
Access levels (private/protected/public)Да, enforced при parseДа
Cross-project refДа, через dependencies.yml + manual manifest distributionДа, automatic manifest discovery
Cross-project lineage в UIТолько локальный dbt docsFull в Explorer
Cross-project access policiesТолько через manifest validation+ UI governance
Cross-project performance optimizationsManualOptimized internally
Cross-project version policiesManual через deprecation_dateUI deprecation tracking

Если у вас Core — Mesh реализуем, но требует существенной инженерной работы для production-grade setup. В Cloud Enterprise это работает “из коробки”.


Что middle-инженер должен уметь

  1. Объяснить проблему, которую решает Mesh, и когда он преждевременен (size + team count + CI bottleneck).
  2. Определить model groups в _models.yml с owner.
  3. Прописать access (private/protected/public) на моделях, понимая, что enforced.
  4. Знать синтаксис cross-project ref: {{ ref('project_name', 'model_name') }}.
  5. Назвать elements governance pattern: public API contracts, deprecation workflow, ownership.
  6. Аргументировать, готова ли ваша команда к Mesh.

Попробуй сам

В вашем текущем dbt-проекте (если он >100 моделей):

  1. Identify groups. Сгруппируйте модели по domain (marketing / finance / product / platform). Сколько groups получается?
  2. Identify owners. Кто owner каждой group? Если “никто” — это знак, что Mesh преждевременен (или organization issue).
  3. Identify access. Какие модели должны быть public (используются за пределами своей группы)? Какие private?
  4. Map cross-group dependencies. Какая группа ref’ит какую? Является ли граф ациклическим?

Это упражнение — pre-work для Mesh, даже если вы не планируете split. Просто наличие этой структуры улучшает governance.

Откройте https://docs.getdbt.com/docs/mesh/about-mesh — официальная документация Mesh. Изучите концепции model_groups, access, cross-project ref. Senior-детали (versioning, performance, governance patterns) — в dbt III.


Проверка знанийKnowledge check
Компания на dbt-core, монорепо 350 моделей, 3 data-команды (marketing/finance/product) делящие проект. Сейчас CI ~25 минут, regressions между командами happens 2-3 раза в спринт. Стоит ли split в Mesh? Какие промежуточные шаги имеет смысл сделать сначала?
ОтветAnswer
Прямой ответ: Mesh имеет смысл рассмотреть, но прежде чем split — реализовать промежуточные шаги. Условия для Mesh подходят: 350 моделей (близко к порогу 500), 3 команды с конфликтами, CI 25 минут. НО сначала: (1) Реализовать groups + access внутри монорепо. Каждая команда — group с owner. Public/private access — установить контракты между командами. Это даёт 70% benefits Mesh без overhead split'а. (2) Slim CI с state:modified+ + defer. Если CI 25 минут на полный build — после Slim CI должно быть 5-10 минут. Это часто eliminate'ит boot CI bottleneck без архитектурных изменений. (3) Понять причины regressions: это violation public/private (фикс через access) или просто отсутствие тестов на boundaries (фикс через тесты)? (4) Установить deprecation workflow на breaking changes между командами. После 1-3 месяцев работы с groups + access + Slim CI — оценить, нужен ли split. Часто оказывается, что нет: проблемы решены без архитектурных изменений. Mesh добавляет deployment coordination, version management, manifest distribution — это реальный operational overhead. Преждевременный Mesh может быть хуже, чем хорошо организованный монорепо. На dbt-core split в Mesh ещё дороже, чем в Cloud Enterprise — нужно решать manifest distribution руками.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 6. Какие проблемы дозревают в монолитном dbt-проекте на 800+ моделей с 4 командами, которые мотивируют переход на dbt Mesh?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5