Решение о структуре вашего dbt Mesh
Изучение паттернов mesh
При переходе на многопроектную архитектуру, где провести границы между проектами?
Как организовать потоки данных в мире, где вместо одного dbt DAG у вас есть несколько проектов, взаимодействующих друг с другом, каждый из которых состоит из своего собственного DAG?
Принятие паттерна Mesh — это не универсальный подход «один размер для всех». На самом деле всё наоборот! Речь идёт о том, чтобы адаптировать структуру проекта под вашу команду и ваши данные. Теперь вы можете сформировать граф знаний организации в соответствии с графом людей в организации, сближая людей и данные, а не жертвуя одним ради другого.
Хотя нет единственного лучшего способа реализации этого паттерна, есть несколько общих точек принятия решений, которые будут полезны для рассмотрения.
На высоком уровне вам нужно будет решить:
- Где провести границы между вашими dbt проектами — т.е. как определить, где разделить ваш DAG и какие модели в какой проект включить?
- Как управлять вашим кодом — хотите ли вы, чтобы несколько dbt проектов находились в одном репозитории (моно-репо) или хотите иметь несколько репозиториев с одним репозиторием на проект?
Чтобы помочь вам начать работу, ознакомьтесь с нашим Quickstart with Mesh или пройдите наш онлайн‑курс Mesh course, чтобы узнать больше!
Определите интерфейсы вашего проекта, разделив DAG
Первое (и, возможно, самое сложное!) решение при переходе на многопроектную архитектуру — это решение о том, где провести линию в вашем DAG, чтобы определить интерфейсы между вашими проектами. Давайте рассмотрим некоторые термины для обсуждения дизайна этих паттернов.
Вертикальные разделения
Вертикальные разделения выделяют слои трансформации в порядке DAG. Рассмотрим некоторые примеры.
- Разделение слоев подготовки и витрин для создания более строго контролируемого, общего набора компонентов, на которых строятся другие проекты, но не могут их редактировать.
- Изоляция ранних моделей для требований безопасности и управления для выделения и маскировки данных PII, чтобы потребители на нижних уровнях не могли к ним получить доступ, является распространенным случаем использования вертикального разделения.
- Защита сложных или дорогих данных для изоляции больших или сложных моделей, которые дорого запускать, чтобы они были защищены от случайного выбора, независимо разворачиваемы и легче отлаживаемы при возникновении проблем.
Горизонтальные разделения
Горизонтальные разделения разделяют ваш DAG на основе источника или домена. Эти разделения часто основаны на форме и размере данных и на том, как они используются. Рассмотрим некоторые возможности для горизонтального разделения.
- Паттерны потребления команд. Например, выделение потока данных команды маркетинга в отдельный проект.
- Данные из разных источников. Например, данные событий clickstream и транзакционные данные электронной коммерции могут нуждаться в независимом моделировании друг от друга.
- Рабочие процессы команд. Например, если две встроенные группы работают с разной скоростью, вы можете захотеть разделить проекты, чтобы они могли двигаться независимо.
- Это не взаимоисключающие техники. Вы должны рассмотреть оба типа разделений и комбинировать их любым образом, который имеет смысл для вашей организации.
- Выберите один тип разделения и сосредоточьтесь на нем сначала. Если у вас есть топология команды в виде "звезда и спицы", например, сначала разберите центральный проект платформы, прежде чем разделять оставшиеся на домены. Затем, если вам нужно разделить эти домены горизонтально, вы можете сосредоточиться на этом после.
- DRY применяется к исходным данным, а не только к коду. Независимо от вашей стратегии, вы не должны использовать одни и те же строки и столбцы в нескольких узлах. Работая в паттерне mesh, становится все более важным не дублировать логику или данные.
Упрощенный dbt DAG с двумя пунктирными линиями, представляющими как вертикальное, так и горизонтальное разделение.
Упрощённый dbt DAG с двумя пунктирными линиями, представляющими вертикальное и горизонтальное разделение.Определите вашу стратегию работы с git
С момента запуска dbt Mesh, наиболее распространенный паттерн, который мы видели, это тот, где проекты 1:1 соответствуют командам, и каждый проект имеет свою собственную кодовую базу в своем собственном репозитории. Это не жесткое правило: некоторые организации хотят, чтобы несколько команд работали из одного репозитория, и некоторые команды владеют несколькими доменами, которые неудобно держать вместе.
Пользователям может потребоваться вносить модели в несколько проектов, и это нормально. Будет некоторое трение при этом, по сравнению с одним репозиторием, но это полезное трение, особенно если вы вносите изменения из "спицы" в "звезду". Это должно рассматриваться как внесение изменений в API, с которым другая команда будет жить некоторое время. Вы должны быть обеспокоены, если ваши коллеги обнаружат, что им нужно часто (каждую неделю) вносить согласованные изменения в несколько проектов, или это является ключевым предварительным условием для ~20%+ их работы.
Проекты, разделения и команды
С момента запуска Mesh самым распространённым паттерном, который мы наблюдаем, является ситуация, когда проекты соотносятся с командами в пропорции 1:1, и каждый проект имеет собственную кодовую базу в отдельном репозитории. Это не жёсткое правило: в некоторых организациях несколько команд работают в одном репозитории, а у некоторых команд есть несколько доменов, которые неудобно держать объединёнными.
Пользователям может понадобиться вносить изменения в модели сразу в нескольких проектах — и это нормально. При таком подходе по сравнению с единым репозиторием возникает некоторое трение, но это полезное трение, особенно когда изменение прокидывается из «спицы» (spoke) в «хаб» (hub). К этому стоит относиться так же, как к изменению API — такому, с которым другой команде предстоит жить в течение длительного времени. Повод для беспокойства возникает в том случае, если ваши коллеги регулярно (каждую неделю) сталкиваются с необходимостью делать согласованные изменения сразу в нескольких проектах или если это является обязательным предварительным условием для ~20% и более их работы.
Обнаружение циклов
Вы можете включить двунаправленные зависимости между проектами, чтобы эти связи могли идти в любом направлении. Это означает, что проект jaffle_finance может добавить новую модель, которая зависит от любых публичных моделей, созданных проектом jaffle_marketing, при условии, что новая зависимость не вводит циклы на уровне узлов. dbt проверяет наличие циклов между проектами и выдает ошибки, если они обнаружены.
При настройке проектов, которые зависят друг от друга, важно делать это пошагово. Каждый проект должен выполняться и создавать публичные модели, прежде чем исходный проект-производитель сможет взять зависимость от исходного проекта-потребителя. Например, порядок действий для простой настройки из двух проектов будет следующим:
- Проект
project_aвыполняется в среде развертывания и создает публичные модели. - Проект
project_bдобавляетproject_aв качестве зависимости. - Проект
project_bвыполняется в среде развертывания и создает публичные модели. - Проект
project_aдобавляетproject_bв качестве зависимости.
Советы и рекомендации
Страница реализации предоставляет более подробные примеры того, как разделить монолитный проект на несколько проектов. Вот несколько советов, которые помогут вам начать, когда вы рассматриваете методы разделения, перечисленные выше, для ваших собственных проектов:
- Начните с рисования диаграммы ваших команд, занимающихся обработкой данных. Соотнесите каждую команду с одним dbt проектом. Если у вас уже есть существующий монолитный проект, и вы подключаете новые команды, это может быть так же просто, как объявить существующий проект вашим "центром" и создать новые "спицевые" песочницы для каждой команды.
- Отделите общие основы, когда вы знаете, что нескольким нижестоящим командам потребуется один и тот же источник данных. Эти данные могут быть переданы в централизованный центр или выделены в отдельный основной проект. вам нужны некоторые разделения, чтобы облегчить другие разделения, например, модели подготовки источников в A, которые используются как в B, так и в C (отсутствие циклов проекта).
- Разделите снова, чтобы ввести намеренное трение и инкапсулировать определенный набор моделей (например, для внешнего экспорта).
- Объедините снова, если у вас есть "горячие пути" подмножества DAG, которые вам нужно развернуть с низкой задержкой, потому что они питают отчеты в приложении или операционную аналитику. Может иметь смысл, чтобы другая выделенная команда владела этими моделями данных (см. принцип 1), аналогично тому, как программные сервисы с существенно различными характеристиками производительности часто требуют выделенной инфраструктуры, архитектуры и персонала.

