Workflow-менеджмент з Apache Airflow. Огляд інструменту

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.

Привіт! Мене звати Дмитро Казанжи, я працюю в компанії TEAM International Services, Inc як Data Engineer. Нещодавно відбулась зустріч Kyiv Data Science Club, де я розповідав про створення і менеджмент пайплайнів обробки даних з Apache Airflow.

Для чого потрібна оркестрація

Якщо вся ваша робота з даними у сховищі зводиться до того, щоб зробити ad-hoc експорт у Excel, то напевно, що в оркестрації немає сенсу. Проте якщо компанія отримує інсайти з даних, які їй належать, або це компанія, побудована навколо обробки даних, то процес обов’язково буде набагато складнішим.

Наприклад, ваша компанія обробляє великі масиви даних і надає своїм клієнтам цінні поради: у такому випадку процес може виглядати наступним чином. Щоночі в S3-бакеті у вашого провайдера даних з’являються файли з «сирими» даними. Але так вийшло, що ваша компанія обрала Google Cloud Platform, тому в першу чергу необхідно перенести ці файли у корпоративний Cloud Storage. Після цього дані необхідно завантажити у сховище даних BigQuery, де і буде відбуватись подальша обробка. Вже в BigQuery складними SQL скриптами ви фільтруєте помилкові записи, проводите агрегацію і збагачення даних.

Уявімо, що отримані дані необхідно якимось чином провалідувати через сторонній API, але даних так багато, що цей процес треба розпаралелити, тому вам необхідно створити Dataproc кластер, куди буде надсилатись певний файл з кодом на Spark, а результат зберегти у спеціальну таблицю в BigQuery. Коли результуюча таблиця вже оновлена, вам необхідно тригернути оновлення Tableau дашборда, який вже підключений до цієї ж таблиці, щоб вже зранку кінцевий користувач бачив нові дані.

Можливі і набагато складніші пайплайни, де одні пайплайни залежать від інших.

Image Source

Саме для того, щоб описаний вище процес відбувався за графіком і в певній послідовності, вам потрібен workflow менеджер. Останні кілька років де-факто стандартним інструментом вважається Apache Airflow.

Історія

Airflow з’явився на світ як внутрішній проєкт компанії Airbnb у 2014 році, але з самого початку він був open-source. Автором проєкту є Максим Бушемін, який також започаткував розробку BI-інструменту з відкритим кодом — Apache Superset. Вже у 2016 році проєкт переходить у Apache Incubator, а у 2019 стає top-level проєктом Apache Software Foundation. Проєкт написаний на Python, на ньому же й описується вся послідовність задач.

Компоненти

Конфігурація залежить від того, яку кількість паралельних задач має виконувати цей інструмент. Уже від конфігурації залежить, які компоненти вам необхідні. Обов’язкові компоненти:

  • Metadata database — це база даних, де Airflow зберігає всю необхідну мета-інформацію про поточні та попередні задачі, їхній статус та результат виконання. Рекомендується використовувати СУБД Postgres для більш стабільної і ефективної роботи, проте при необхідності можна підключити MySQL, MSSQL та SQLite (з обмеженнями).
  • Scheduler — компонент системи, який парсить файли з описаними пайплайнами та, при необхідності, передає на виконання до Executor.
  • Webserver — це застосунок, що використовує Flask та запускається через gunicorn. Основна роль цього компоненту — це графічне відображення пайплайну та ходу його виконання.

Компоненти, що залежать від конфігурації і задач:

  • Triggerer — по суті є імплементацією event-loop для асинхронних операторів, які вперше з’явилися у версії 2.2. Зараз таких операторів дуже мало, тому якщо ви не плануєте їх використовувати, то і немає необхідності запускати компоненту Triggerer.
  • Worker — це модифікований воркер з бібліотеки Celery. Ви можете запустити стільки воркерів, скільки вам необхідно, проте для цього необхідно вказати CeleryExecutor.

Виконання

Очевидно, що Python-код, який описує задачі і їхній порядок, має десь виконуватись. Якраз цим і займається Executor. Airflow підтримує кілька типів виконавців:

Тип Executor’аДе виконуються задачі
SequentialExecutorЛокально, в основному потоці виконання
LocalExecutorЛокально, в окремих процесах ОС
CeleryExecutorУ Celery воркерах
DaskExecutorУ вузлах Dask кластеру
KubernetesExecutorУ Kubernetes подах

Для production-у частіше за все використовуються CeleryExecutor та KubernetesExecutor. Це треба врахувати і під час побудови пайплайну, щоб між окремими задачами не було залежностей, крім тих, що прописані в самому пайплайні. Тобто кожна задача буде виконуватись у власному ізольованому середовищі та, скоріше за все, у різних фізичних комп’ютерах, тому послідовність задач «скачати файл на диск» та «завантажити файл в хмарне сховище» не буде робочою.

Архітектури

Як ви вже здогадалися, Apache Airflow — це досить гнучкий інструмент, тому його можна конфігурувати точно під конкретні вимоги. Проте існують дві загальновживані архітектури: single-node та multi-node.

Images Source

Детальніше про переваги і недоліки кожного з перерахованик Executor-ів чудово описано у статті.

Встановлення

Є декілька різних способів встановити і запустити Airflow.

  1. Через менеджер пакетів PIP.

Напевно, що це найменш зручний спосіб. Спочатку доведеться встановити всі необхідні залежності, потім налаштувати і запустити СУБД на ваш вибір. Звісно, ви можете обрати SQLite, проте тоді доведеться використовувати SequentialExecutor і пожертвувати паралельністю виконання задач. Після цього бажано створити і активувати віртуальне оточення для Python і вже тоді можна приступати до встановлення і запуску Airflow компонентів.

python -m pip install apache-airflow
airflow webserver
airflow scheduler

Важко перерахувати, скільки може виникнути нюансів при цьому варіанті. Якщо ви використовуєте Linux або MacOS, то напевно, що проблем буде не так багато. Проте для Windows доведеться самостійно компілювати і встановлювати деякі додаткові бібліотеки, тому краще відразу використовуйте WSL.

2. Через окремі Docker-контейнери.

Напевно, що цей спосіб — не найзручніший для встановлення на локальній машині, але може підійти, якщо вам необхідно вручну налаштовувати Airflow-кластер на власних bare-metal серверах.

docker run … postgres
docker run … apache/airflow scheduler
docker run … apache/airflow webserver

3. Через docker-compose.

Це найбільш зручний спосіб для локального запуску. Для цього треба скомпонувати власний docker-compose.yaml файл, або скористатися вже готовими варіантами та виконати

docker-compose up

Більш детально про цей спосіб написано в одному з офіційних туторіалів.

4. Через Astronomer CLI.

Останній спосіб, який я б хотів назвати, не є універсальним, але він чудово підходить для локальної розробки, особливо якщо ваша компанія використовує managed-версію Apache Airflow від компанії Astronomer. Для початку роботи необхідно встановити Astronomer CLI, як вказано в інструкції, та виконати:

astro dev init
astro dev start

Окрім зручності налаштування локальної розробки, через Astronomer CLI дуже легко деплоїти.

Managed версії

Враховуючи популярність цього інструменту, поява managed-версій у хмарних провайдерів була лише питанням часу. Зараз Airflow є на Google Cloud Platform під назвою Cloud Composer та на AWS як Managed Workflows for Apache Airflow (MWAA). Також хмарну версію пропонує Cloud Data Lake провайдер Qubole.

Окремо хотілося б розглянути компанію Astronomer, яку заснували і в якій працюють топ-контриб’ютори опенсорсного проєкту. Також ця компанія проводить багато вебінарів, присвячених цьому інструменту, і має два підготовчих курси з сертифікаціюю з Apache Airflow.

Інтерфейс

Галерею скріншотів можна переглянути тут.

Концепт

Перейдемо до розгляду основних сутностей, які треба знати, коли ви почитаєте роботу з Airflow.

Сутності

Основною сутністю workflow є DAG (directed acyclic graph) — орієнтований ациклічний граф, що об’єднує всі задачі в один пайплайн. Поняття DAG-у зустрічається і в інших популярних інструментах, наприклад в Apache Spark.

Image Source

Вузлами цього графу є Task, який є екземпляром класу Operator. Оператори умовно можна поділити на:

  • Action operator — виконує певну дію, як DataprocSubmitSparkJobOperatorі
  • Transfer operator — переносить дані з одного місця в інше, як S3ToGCSOperator
  • Sensor operator — очікує певної події, як BigQueryTablePartitionExistenceSensor

В основному, пайплайни запускаються з певною регулярністю, тому існує поняття Task Instance — екземпляр певного оператора з міткою часу, коли відбувся запуск пайплайну. Для прикладу:

  • PythonOperator — виконує певну python функцію.
  • BashOperator — запускає bash команду або скрипт.
  • PostgresOperator — виконує SQL запит у PostgreSQL.
  • KubernetesPodOperator — запускає pod на кластері і виконує певні команди.

А через веб-інтерфейс є можливість створювати Variables на кшталт змінних оточення і Connections — дані необхідні для підключення для зовнішніх ресурсів.

Обидві сутності зберігаються в базі метаданих та доступні з усіх компонентів системи, при чому паролі для Connection зберігаються у зашифрованому вигляді.

Також потрібно згадати і про Hook — інтерфейс для роботи з зовнішніми сервісами. Хуки — це обгортки над популярними бібліотеками для роботи з певним інструментом, наприклад хуки для роботи з реляційними СУБД використовують SQLAlchemy, а хуки для роботи з AWS використовують бібліотеку boto3.

Хуків і операторів наразі нараховується близько 850, тому є актуальною ідея реєстру для зручного пошуку. Якраз це недавно було імплементовано у Astronomer Registry. Але навіть якщо ви не знайшли потрібний вам оператор, то ви можете з легкістю написати свій, наслідуючись від класу BaseOperator.

Додаткові бібліотеки

Airflow має модульну структуру і для повноцінної роботи в певній конфігурації потребує додаткових бібліотек, які можуть встановлюватись разом з Airflow. Наприклад, якщо ви хочете налаштувати CeleryExecutor, то вам необхідно також встановити бібліотеки celery та redis, якщо ви хочете налаштувати іншу аутентифікацію, то вам необхідні відповідні бібліотеки. Це все core extras.

Зараз Airflow підтримує роботу більше ніж з 50 сторонніми ресурсами, але немає сенсу їх всі одночасно встановлювати. Тобто якщо для роботи вам потрібна тільки інтеграція з Snowflake та AWS, то ви встановлюєте відповідні інтеграції і не ставите бібліотеки для роботи, наприклад, з Oracle, Neo4j та MongoDB. Це providers extras.

Більш детально про це в офіційній документації.

Створення DAG-ів

Основні моменти

Ми дійшли до основного питання: як виглядає пайплайн у Airflow.

Спершу імпортуємо необхідні бібліотеки і функції.

import requests
import pandas as pd
from pathlib import Path
from airflow.models import DAG
from airflow.operators.python import PythonOperator

Далі напишемо дві python-функції, які роблять певні дії. Але хочу уточнити, що такий підхід небажаний через те, що частіше за все для production використовується CeleryExecutor або KubernetesExecutor, тому друга функція поверне помилку, бо в її оточенні не буде файлу.

def download_data_fn():
   url = 'https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv'
   resp = requests.get(url)
   Path('titanic.csv').write_text(resp.content.decode())

def pivot_data_fn():
   df = pd.read_csv('titanic.csv')
   df = df.pivot_table(index='Sex', columns='Pclass', values='Name', aggfunc='count')
   df.reset_index().to_csv('titanic_pivoted.csv')

Ну і далі створюємо екземпляр DAG-у і екземпляри операторів — таски. Перша умова — dag_id має бути унікальним в межах всього деплоймента. Друга — всі task_id також мають бути унікальними в межах одного DAG-у.

with DAG(dag_id='titanic_dag', schedule_interval='*/9 * * * *') as dag:
   download_data = PythonOperator(
       task_id='download_data',
       python_callable=download_data_fn,
       dag=dag,
   )

   pivot_data = PythonOperator(
       task_id='pivot_data',
       python_callable=pivot_data_fn,
       dag=dag,
   )

Починаючи з другої версії Airflow, немає необхідності давати на вхід оператору екземпляр DAG-у, якщо оператор знаходиться в контексті DAG-у.

Наступним кроком вказуємо залежності між тасками, тобто порядок їх виконання.

download_data >> pivot_data
# pivot_data << download_data 
# download_data.set_downstream(pivot_data)
# pivot_data.set_upstream(download_data)

Зазначу, що кожен з вищевказаних варіантів створює одну і ту ж залежність, і ви можете використати будь-який з них. Рекомендується використовувати або тільки виклики метода, або тільки бітшифт оператор.

Написаний файл має бути в директорії, де Airflow шукає DAG-и. За замовчуванням, це < strong >$AIRFLOW_HOME/dags. Після цього вже scheduler буде ставити цей пайплайн в чергу виконання, а Executor буде виконувати цей пайплайн кожні дев’ять хвилин.

Taskflow API

Також з Airflow 2.0 з’явилась можливість значно спростити використання функцій.

import requests
import pandas as pd
from pathlib import Path
from airflow.models import DAG
from airflow.decorators import task

with DAG(dag_id='titanic_dag', schedule_interval='*/9 * * * *') as dag:
   @task
   def download_data():
       url = 'https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv'
       resp = requests.get(url)
       Path('titanic.csv').write_text(resp.content.decode())

   @task
   def pivot_data():
       df = pd.read_csv('titanic.csv')
       df = df.pivot_table(index='Sex', columns='Pclass', values='Name', aggfunc='count')
       df.reset_index().to_csv('titanic_pivoted.csv')

У цьому прикладі декоратор @task приймає на вхід python-функцію і повертає екземпляр PythonOperator-у. При цьому залежності прописуються наступними способами:

 pivot_data(download_data())
   # download_data_op = download_data()
   # pivot_data_op = pivot_data()
   # download_data_op >> pivot_data_op

Трохи про start_date і schedule_interval

Майже у кожного, хто тільки починає працювати з Airflow, виникають проблеми з розумінням інтервалів і дат. Перед тим як почати, варто уточнити, що Airflow використовує тільки UTC в процесі роботи.

Кожен DAG приймає такі параметри як start_date та schedule_interval. start_date, визначає, з якого часу пайплайн можна запускати, а schedule_interval показує, з якою періодичністю необхідно запускати. Цікаво, що schedule_interval може бути відносним, якщо ми вказали timedelta, або абсолютним, якщо це cron expression.

У першому випадку, запуск пайплану відбудеться у start_date + schedule_interval, але execution_date буде дорівнювати start_date. У другому ж випадку логіка scheduler-а наступна — перший execution_date — це перша дата і час після start_date, яка задовольняє умовам schedule_interval, а перший запуск пайплайна, відповідно, це наступні такі дата і час.

Image Source

Щоб описати розклад, який зображено на малюнку вище, ми можемо використати:

  • schedule_interval = timedelta(hours=1) та start_date = datetime(2021, 01, 26, 5, 0, 0)
  • schedule_interval = ’0 * * * *’, а start_date може бути будь яким часом від datetime(2021, 01, 26, 4, 0, 1) до datetime(2021, 01, 26, 5, 0, 0)

Через певну плутанину, розробники вирішили відмовитись від цієї назви і натомість прийняли рішення, що у кожного запуска будуть два параметри data_interval_start та data_interval_end. Перший показує, коли востаннє запускався пайплайн, а другий — поточний запуск.

XComs

Що робити, якщо між задачами є додаткові залежності, а не тільки умова, що «Задача Б» має запускатись після «Задачі Б»?

Цю проблему вирішують XComs (cross-task comminications). Завдяки цьому механізму задача може записувати в базу метаданих будь-які дані, а інша задача — їх читати. Візьмемо за основу минулий приклад, але в цьому випадку припустимо, що назва файлу може бути довільною і буде генеруватись першою задачею.

def download_data_fn(**context):
   filename = 'titanic.csv'
   url = 'https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv'
   resp = requests.get(url)
   Path(filename).write_text(resp.content.decode())
   #context['ti'].xcom_push(key='filename', value=filename) # option 1
   return filename # option 2


def pivot_data_fn(ti, **context):
   # filename = ti.xcom_pull(task_ids=['download_data'], key='filename') # option 1
   filename = ti.xcom_pull(task_ids=['download_data'], key='return_value') # option 2
   df = pd.read_csv(filename)
   df = df.pivot_table(index='Sex', columns='Pclass', values='Name', aggfunc='count')
   df.reset_index().to_csv('titanic_pivoted.csv')

with DAG(dag_id='titanic_dag', schedule_interval='*/9 * * * *') as dag:
   download_data = PythonOperator(
       task_id='download_data',
       python_callable=download_data_fn,
       provide_context=True,
   )

   pivot_data = PythonOperator(
       task_id='pivot_data',
       python_callable=pivot_data_fn,
       provide_context=True,
   )

   download_data >> pivot_data

Як бачимо, є кілька способів записувати дані в XCom, проте слід бути уважними і передавати через цей механізм лише невеликі дані. По-перше, це уповільнить роботу бази, а перевищення певних лімітів, які залежать від СУБД, викличе помилку, по-друге — слід пам’ятати, що Airflow — це оркестратор, і він не призначений для обробки даних.

Недоліки

Важко помилитися, якщо сказати, що у кожного досить складного інструменту є певні особливості, до яких можна звикнути, і певні недоліки, які дуже сильно заважають. Для мене таким недоліком є складний процес розробки.

Тобто для того, щоб почати розробляти, необхідно встановити і запустити Airflow локально. А для того, щоб відтестувати, необхідно прописати всі Connections та Variables. Кількість перших може рахуватись десятками, а других — сотнями. Це не кажучи про те, що для тестування необхідно мати development та/або staging оточення.

Альтернативи

Незважаючи на лідируючі позиції Airflow як workflow менеджера, в нього є конкуренти. Всі з тих, що я хотів би привести в приклад, є open-source проєктами та мають певну спільноту навколо себе.

Найбільш перспективним зараз виглядає Dagster, на це натякає раунд А інвестицій у компанію Elementl, яка займається розробкою та комерціалізацією цього інструменту. Ще зовсім недавно основним конкурентом Airflow можна було вважати інструмент Prefect, який теж розробляється однойменною компанією. Стрімко втрачає позиції Spotify Luigi, проте все ще використовується у багатьох компаніях через легкість у користуванні. Ну і наприкінці я хотів би згадати Apache Oozie як представника екосистеми Apache Hadoop. Цей проєкт дуже повільно розвивається, проте має вузьку нішу. Також я б порадив звернути увагу на такі інструменти як Flyte, що розробляється компанією Lyft та Azkaban, в який багато контриб’ютить HashiCorp.

Напевно, що до альтернатив можна було б віднести і такі інструменти як dbt, Apache NiFi, а також AWS Glue, Azure Data Factory, Databricks Live Tables і безліч подібних інструментів для побудови ETL/ELT пайплайнів.

Посилання

Подивитись відеозапис моєї доповіді на Kyiv Data Science Club можна за посиланням, якщо необхідно, то ось слайди та проєкт з кодом.

Ну і наостанок поділюсь посиланнями, які, на мою думку, допоможуть у процесі вивчення цього інструменту та полегшують роботу з ним.

Хочу подякувати Андрію Солдатенку та Тарасу Ярощуку за допомогу у підготовці цієї статті.

Понравилась статья? Нажимай «Нравится» внизу. Это поможет автору выиграть подарок в программе #ПишуНаDOU

👍НравитсяПонравилось7
В избранноеВ избранном1
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Трохи критики Airflow і порівняння з Prefect та Dagster
towardsdatascience.com/...​-inside-look-6074781c9b77

За статью спасибо!
Особенно про StartDate в планировщике. Такое рAгульное решение встречал только в AirFlow и каждый кто начинал с ним работать наступал на эти грабли. Коллеги сошлись на мнении что этот скедулер писали люди далекие от типичных решений ETL.
Ну и dbt — это далеко не конкурент AirFlow. dbt реализует не больше 20-30% того что умеет AirFlow. И писать логику на Jinja, как по мне, это еще то извращение.

Такое рAгульное решение встречал только

Ну його писали для внутрішніх потреб Airbnb, а він став популярним через те, що закривав певну нішу. Мені це стало звичним, і нічого особливого в цій реалізації не бачу, але на початку роботи було, м’яко кажучи, незрозуміло :)

И писать логику на Jinja

логіка ж на SQL пишеться, точніше моделюється. А Jinja там додає гнучкості.
Хоча колись в чатах бачив, що хтось зробив щось на кшталт
WHERE col IN ({% for i in range(55) %} {{i}}, {% endfor %})

Airflow це добре, але його треба моніторити. Що впало, що не спрацювало, що довго бігло.

Таке рішення розробляє компанія Databand: databand.ai
Ми вміємо безшовно інтегруватися в існуючу структуру airflow і тягнути звідти абсолютно всю інфу про даги та стан їх виконання. На будь-який параметр можна робити алерти, а ще можна інтегрувати наше SDK в Python/Java код та робити свої кастомні метрики або data quality checks на будь-які датасети.

Ще ми вміємо автоматично збирати купу інфи із спарк джоб та підтягувати її у даги.

Azkaban, в який багато контриб’ютить HashiCorp

Використовується надзвичайно рідко, та в тих конторах, де більше пишуть під JVM і немає пітоністів. По можливостям він значно-значно-значно поступається Airflow. Втім, з ним ми теж вміємо інтегруватися та відстежувати стан виконання джоб.

p.s.: we are hiring!

Дякую за детальне технічне пояснення цього рішення! Виглядає дуже складно. Із подібних рішень я стикався з Azure Data Factory, Databricks, про яке ви згадуєте як альтернативу. ADF набагато простіше на мою думку. Процес налаштування схожий візуально на кубики, з якими впорається навіть домогосподарка )) При цьому ви зможете налаштувати ті самі процеси трансформації даних ETL зі скриптами на пітоні та запускати їх за розкладом.

Так ADF чудовий інструмент, якщо вся дата платформа зосереджена в Azure.
Але є компанії з multi-cloud, або мігрують з GCP на AWS (чи навпаки).
Одне з переваг Airflow перед іншими оркестраторами — це наявність великої кількості інтеграцій

Недоліки

упущен имхо главный — невероятно кривая (в 1.х вообще кошмар, но в 2.х пока не сильно лучше) организация работы xcom+execution_date, которая делает построение сложных цепочек, состоящих из нескольких dag’ов с разными schedule_interval или аггрегацию в больший период — если не невозможным, то достаточно муторным

Згоден. Я це мав на увазі, коли писав

Для мене таким недоліком є складний процес розробки.

Але разом з тим я не думаю, що описаний вами випадок буде легше імплементувати в Dagster/Prefect

Ну и top 1 ошибка начинающих в Airflow — не читать в глобальном контексте дага!

atlas_conn = BaseHook.get_connection(f'atlas')

В случае AWS SSM бекенда, ждите 502 от бото.

Дуже доречне зауваження. Дякую

Советую использовать Airflow как чистый оркестратор и работу, например обработку данных, делать в других системах (e. g. Batch/Glue/Spark/), в таком случае можно легко обойтись даже ParallelExecutor и сильно облегчить себе жизни.

В нас, наприклад, на одному інстансі більше 100 DAG-ів і без CeleryExecutor, нажаль, не обійтися

У меня в «offload» варианте тоже штук 100-200 крутится на дохлом ECS с 4Гб памяти и кажется 2 или может 4 ядра. Просто у меня интересный деплоймент — под каждый проект/продукт отдельный airflow, который деплоится автоматически под продуктовую ветку.

В цілому на нашому проекті так само але х2.5 (prod, stg, і іноді dev).
На проді не ризикуємо, тому відразу обираємо Celery/Kubernetes executor. А от на деві часто LocalExecutor

а чому dbt це альтернатива airflow? dbt це не оркестратор. Тим більше, в астрономера є гайд як запускати дбт таски в еірфлові

В dbt теж можна будувати пайплани трансформації даних, через моделювання. А у клауд версії можна виконувати ’dbt run’ за розкладом.
Якщо в організації, наприклад, лише одне сховище даних і всі трансформації відбуваються в ній, то використання Airflow може бути недоцільним

Можна допустити ситуацію, коли в репозиторії dbt багато різних «пайплайнів» нехай. І доводиться розбивати dbt run на dbt run -m part1, dbt run -m part2...
Я маю на увазі що пайплайни можна будувати, але дбт не відповідає за скедулення тасок. Для запуску dbt тасок використовують інші тули такі як airflow, prefect, crons ...
(dbt != dbt cloud, де можна назначати скедулення)

Абсолютно згоден, що

dbt != dbt cloud

Проте в моему розумінні оркестрація не стільки запуск за певним розкладом, скільки запуск задач у відносній послідовності, типу «А перед Б, а В після Б».
Якщо я не помиляюсь, то у теж Luigi немає production-ready планувальника, але він вважається оркестратором

Подписаться на комментарии