top of page

Почему внешние оркестраторы для DWH — это карго-культ? Знакомимся с In-Database фреймворком DBLiner

3 дня назад
5 мин. чтения

Каждый раз, когда в компании встает задача построить корпоративное хранилище данных (DWH) на базе PostgreSQL или массивно-параллельной СУБД Greenplum, архитекторы на автопилоте открывают привычный стек: Apache Airflow, Dagster или Prefect.

Схема выглядит классически: поднимается тяжелая внешняя инфраструктура, разворачиваются воркеры на Python, которые по расписанию просыпаются, открывают сессию к СУБД и отправляют туда одну-единственную строчку:


INSERT INTO marts.customer_360 SELECT ... FROM staging.events;

Завершен ли на этом процесс? Нет. Внешний воркер на Python продолжает висеть в памяти и часами ждет, пока MPP-кластер ворочает терабайты данных на своих дисках. Если на стыке сети моргнет линк — сессия отвалится, Airflow запишет ошибку, и инженерам придется вручную перезапускать упавший DAG.

Но зачем разворачивать, контейнеризировать и поддерживать сложную внешнюю систему, если сама СУБД (особенно масштаба Greenplum) — это и есть мощнейший вычислительного комплекс?

Мы решили сломать этот карго-культ и перенести слой управления (Control Plane) туда, где ему и место — прямо в базу данных. Встречайте DBLiner — легковесный Data Orchestration Framework, написанный целиком на PL/pgSQL. Что примечательно, фреймворк развивает тот же независимый разработчик (raoote), который создал CerebroSQL — бесплатный инструмент для работы с базами данных. Вместе они образуют бесшовную экосистему: в CerebroSQL вы пишете и отлаживаете SQL-логику витрин, а DBLiner тут же внутри СУБД берет на себя её оркестрацию.



В чем фундаментальная проблема внешних воркеров для DWH?

В современной концепции ELT (Extract-Load-Transform) фаза трансформации данных на 100% происходит внутри БД. Внешний оркестратор в этой схеме выполняет лишь роль «будильника» и диспетчера зависимостей. Натягивание веб-ориентированных инструментов на тяжелые базы данных порождает три системные проблемы:


1. Сетевые накладные расходы и хрупкость сессий: Внешние оркестраторы держат открытые TCP-соединения часами. Любой сетевой таймаут убивает долгоиграющий процесс, хотя на самой базе данных расчет мог успешно завершиться.

2. Инфраструктурный оверхед: Ради банального запуска SQL-скриптов по цепочке вам нужно администрировать Kubernetes-поды для Airflow, следить за синхронизацией файлов DAG-ов на Python, настраивать CI/CD и мониторить Celery/Redis.

3. «Слепая зона» для DBA: Администраторы базы данных видят в процессах сотни разрозненных тяжелых запросов от одного сервисного пользователя Airflow. Им крайне тяжело сопоставить конкретный SELECT с верхнеуровневой бизнес-задачей или витриной.



Архитектура DBLiner: Полная изоляция внутри СУБД

Все компоненты DBLiner разворачиваются внутри базы данных в системной схеме dbliner с помощью одного скрипта Install.sql. Фреймворк не лезет в бизнес-логику — вы по-прежнему пишете привычные хранимые функции или SQL-шаги. Он берет на себя рутину: расписание, контроль зависимостей, логирование, алертинг и обработку ошибок.

Принципиальное отличие DBLiner от других внутрибазовых «планировщиков» — это четкое разделение регламентного потока и ad-hoc очередей пересчета:


[ БИЗНЕС-ЛОГИКА (Шаги SQL) в dm$sql ]

│

┌──────────────────┴──────────────────┐

▼ ▼

[ РЕГЛАМЕНТ: Реестр dm$scheduller ] [ AD-HOC: Очередь пересчета dm$queues ]

│ │

▼ ▼

dbliner.run_scheduler(worker_id) dbliner.run_task()

│ │

└──────────────────┬──────────────────┘

▼

[ Управление блокировками: pg_advisory_lock ]

│

▼

[ Изоляция через сессионный контекст ]

│

▼

[ Логирование в dm$operation_log ]


1. Регламентный конвейер (dm$scheduller)

Эта сущность отвечает за регулярный, расписанный по часам/дням/месяцам накат ETL и сборку витрин. Ядро планировщика запускается функцией dbliner.run_scheduler(worker_id). Она автоматически сканирует технологическую карту зависимостей (таблица dm$mapping), выстраивает правильный порядок выполнения и следит, чтобы финальная витрина не начала считаться раньше, чем обновятся сырые стейджинги.

Очередь параллельного пересчета (dm$queues)

В реальном продакшене аналитикам постоянно нужно пересчитать историю за прошлый квартал с новыми коэффициентами или перезапустить упавший кусок данных с произвольными параметрами.

В DBLiner для этого спроектирована автономная очередь dm$queues, управляемая функцией dbliner.run_task(). Вы можете закинуть туда любые ad-hoc задачи с кастомными параметрами сессии, и они будут выполняться параллельно, никак не мешая основному регламентному расписанию.



Как это решает проблему блокировок (Lock Contention)? Укрощение очередей через pg_advisory_lock

Критики внутрибазовых оркестраторов часто говорят: «Если запустить параллельные потоки, они начнут блокировать таблицы очередей, конкурировать за строки при UPDATE/SELECT, и вся СУБД встанет в бесконечный Deadlock».

Разработчики DBLiner решили эту классическую проблему на уровне дизайна ядра. Вместо перманентных и тяжелых транзакционных блокировок строк (вроде SELECT ... FOR UPDATE), распределение задач и защита от конкуренции параллельных процессов полностью возложены на встроенные рекомендательные блокировки PostgreSQL — pg_advisory_lock.


Как это устроена распределенная координация:

* Блокировки без таблиц: Механизм pg_advisory_lock оперирует абстрактными числовыми ключами в shared-памяти СУБД, вообще не затрагивая строки таблиц. Воркеры мгновенно договариваются между собой, атомарно захватывая нужный ID задачи.

* Контекстная сессионная изоляция: После успешного перехвата ключа через pg_advisory_lock, фреймворк изолирует потоки выполнения с помощью кастомных контекстов сессии СУБД (current_setting / set_config), выделяя каждому потоку собственный изолированный пул переменных (RUNNER1, RUNNER2).


Это позволило свести физическую конкуренцию за ресурсы к полному нулю: параллельные воркеры разбирают задачи атомарно, безопасно и со скоростью оперативной памяти.


dbt vs Airflow vs DBLiner: В чем разница?

Часто инженеры данных говорят: «Если мы хотим делать трансформации внутри базы данных (In-Database T), у нас уже есть dbt (Data Build Tool). Зачем нам еще один инструмент?»

Здесь кроется важное концептуальное различие. dbt — это не оркестратор. dbt умеет компилировать Jinja-шаблоны в SQL и строить граф зависимостей моделей (DAG), но он не умеет работать как постоянный демон, опрашивать очереди, запускаться по сложному временному расписанию (cron) или обрабатывать ad-hoc запросы на пересчет в реальном времени. Чтобы запустить dbt в продакшене, вам все равно приходится заворачивать его во внешний инструмент — Apache Airflow, Prefect или dbt Cloud.

DBLiner — это полноценный Control Plane (оркестратор + планировщик + очередь) внутри самой СУБД.


Критерий

Apache Airflow

Apache Airflow

DBLiner

Где живет логика управления?

На внешнем сервере / K8s кластере (Python)

На внешнем сервере (CLI / Python)

Внутри самой СУБД (Схема dbliner, PL/pgSQL)

Где выполняются вычисления?

СУБД (но сессия держится внешним воркером)

Полностью внутри СУБД

Полностью внутри СУБД (True MPP ELT с пушдауном)

Управление расписанием (Scheduler)

Да (встроенный мощный тайм-лайн движок)

Нет (нужен внешний вызов: cron, Airflow или dbt Cloud)

Да (Таблица dm$scheduller + встроенный движок)

Параллельная ad-hoc очередь

Ограниченно (Trigger DAG Run с передачей параметров)

Нет (запуск всей цепочки команд из терминала вручную)

Да (Сущность dm$queues для параллельного пересчета истории)

Инфраструктурный оверхед

Высокий (нужен Python, Celery, Redis, веб-сервер)

Средний (нужно Python-окружение, git, CLI-раннеры)

Нулевой (разворачивается за 1 запуск через Install.sql)

Инструмент разработки (IDE)

Любой текстовый редактор (VS Code, PyCharm)

VS Code / dbt Cloud

CerebroSQL (родная бесплатная IDE от того же автора) или любая другая IDE



В чем DBLiner выигрывает у dbt на практике?


1. Динамические параметры «на лету» без перекомпиляции: В dbt для изменения параметров запуска (например, пересчитать за конкретную дату) нужно передавать --vars строки через CLI внешнего раннера. В DBLiner вы просто делаете INSERT в таблицу очереди dm$queues с нужными параметрами сессии, и система сама подхватывает их.

2. Меньше промежуточных слоев: Для работы dbt на сервере нужно развернуть Python, настроить профили подключения (profiles.yml), следить за версиями адаптеров (например, dbt-greenplum). DBLiner работает на чистом SQL прямо в вашей консоли базы данных или в интерфейсе CerebroSQL.



Интеграция с экосистемой Big Data (PXF & Greenplum)

Если ваше хранилище построено на Greenplum, DBLiner превращается в ультимативный инструмент управления Data Lakehouse.

Благодаря нативной поддержке фреймворка PXF (Platform Extension Framework), перемещение данных между Hadoop (HDFS/Hive), объектными хранилищами (S3/MinIO) и вашим DWH становится прозрачным SQL-шагом в таблице dm$sql.

При этом DBLiner выступает исключительно как Control Plane (координатор):


* Выполняет pushdown-вычисления прямо на кластере Greenplum.

* Исключает промежуточные сервера-посредники. Данные стримятся напрямую из внешних источников в сегментные ноды СУБД параллельно.

* Контролирует лимиты одновременных PXF-потоков, защищая NameNode вашего Hadoop-кластера от перегрузки.



Родной инструмент разработки: CerebroSQL + DBLiner

Создавать внутрибазовые пайплайны вручную через консольный psql — сомнительное удовольствие. Именно поэтому фреймворк раскрывается на максимум, если использовать его в связке с CerebroSQL.

Поскольку оба продукта созданы одним автором, интерфейс CerebroSQL идеально адаптирован для работы с метаданными DBLiner. Прямо из графического интерфейса бесплатной IDE вы можете:


1. Быстро писать, тестировать и отлаживать SQL-код будущих шагов ETL.

2. Регистрировать пространства задач (Space) и распределять их по департаментам.

3. Мониторить логи выполнения (dm$operation_log) в реальном времени и отслеживать упавшие шаги с точностью до строчки кода.



Что дальше?

Мы получили легкую, полностью автоматизированную систему управления данными, живущую внутри самой СУБД. Никакого Python, никакого оверхеда на инфраструктуру — только чистый SQL, скорость СУБД, безопасные pg_advisory_lock и полный контроль.

В следующей статье мы опустимся на уровень кода: детально разберем внутреннее устройство пула воркеров, посмотрим на исходники механизмов pg_advisory_lock, заглянем под капот контекстных переменных RUNNER и научимся запускать параллельный пересчет истории через ad-hoc очередь dm$queues. Подписывайтесь, чтобы не пропустить!

Исходный код фреймворка открыт под MIT-лицензией и доступен на GitHub: DBLiner

Комментарии

Оценка: 0 из 5 звезд.
Еще нет оценок

Добавить рейтинг
bottom of page