Почему 87% Big Data проектов проваливаются и как этого избежать

freeCodeCamp.org 1 млн 3 ч 3 мин 26 мин 16.01.2024
Главное

Почти 87% проектов в сфере Big Data терпят крах из-за ненадежной инфраструктуры, превращая амбициозные задачи в кладбища данных. Чтобы не попасть в эту статистику, современный дата-инженер должен пройти путь от ручной сборки Docker-контейнеров до оркестрации пайплайнов в Airflow и dbt. Это руководство по превращению хаоса разрозненных SQL-запросов в масштабируемую систему, где даже ошибки становятся фундаментом для надежного кода.

🛠 Введение в Data Engineering и экосистему Docker 0:00

Фундамент данных: почему индустрии нужны инженеры, а не только аналитики 1:06

Современный мир больших данных сталкивается с парадоксальной ситуацией: несмотря на обилие инструментов, от 85% до 87% Big Data-проектов заканчиваются провалом . Как отмечает эксперт Airbyte Джастин Чоу, основная причина кроется не в отсутствии алгоритмов, а в ненадежной инфраструктуре и низком качестве данных . Долгое время компании ожидали, что обязанности по созданию инфраструктуры возьмут на себя дата-сайентисты, однако это привело к некорректному моделированию, избыточности работы и колоссальной текучке кадров среди специалистов по данным . Именно этот инфраструктурный вакуум и призвана заполнить роль дата-инженера .

Спрос на специалистов, способных обеспечить бесперебойный поток качественных данных, отражается и на уровне компенсации: в США медианная зарплата дата-инженера варьируется от 90 до 150 тысяч долларов в год . Помимо финансовой стороны, роль инженера становится критической в эпоху расцвета генеративного ИИ и LLM, таких как ChatGPT . Дата-инженер — это тот, кто гарантирует, что данные для обучения и работы моделей будут:

По сути, дата-инженер создает кровеносную систему для бизнеса, позволяя компании принимать решения на основе фактов, а не интуиции, что напрямую влияет на её конкурентоспособность .

Docker как стандарт индустрии: образы, контейнеры и решение проблемы «на моей машине работает» 3:45

Первым и фундаментальным инструментом в арсенале дата-инженера является Docker — платформа с открытым исходным кодом, которая радикально упрощает процесс сборки и запуска приложений . Главная проблема, которую решает Docker, — это классическая дилемма «на моей машине всё работает, а у коллеги — нет» . Вместо того чтобы вручную настраивать окружение, инженер упаковывает приложение вместе со всеми его зависимостями, библиотеками и конфигурациями в изолированный контейнер .

Для глубокого понимания технологии важно различать три ключевых концепта:

  1. Dockerfile: текстовый файл-инструкция или «чертеж», по которому Docker понимает, как именно нужно собрать приложение .
  2. Docker Image (Образ): исполняемый пакет, созданный на основе Dockerfile. Он включает в себя код, среду выполнения, системные инструменты и настройки . Важнейшая характеристика образа — его иммутабельность (неизменяемость) . Если вам нужно внести изменения, вы не меняете текущий образ, а создаете новый на основе обновленного Dockerfile .
  3. Docker Container (Контейнер): это запущенный экземпляр образа . Если образ — это чертеж здания, то контейнер — это само здание, в котором можно жить (запускать процессы) .

Контейнеры полностью изолированы как от хост-системы, так и друг от друга . Это позволяет, например, запустить три разных экземпляра одного и того же приложения на одной машине: вы можете остановить или удалить один контейнер, и это никак не затронет остальные . Такая легковесная виртуализация обеспечивает воспроизводимость окружения на любом этапе — от локальной разработки до облачных серверов AWS или GCP .

Жизненный цикл контейнера: от написания Dockerfile до запуска локального приложения 8:56

Процесс контейнеризации приложения начинается с подготовки рабочего окружения. Для работы необходим Docker Desktop, который уже включает в себя Docker Compose (инструмент, необходимый для более сложных задач, которые будут рассмотрены позже) . Практический процесс сборки можно разобрать на примере простого Node.js приложения .

В корневой директории проекта создается Dockerfile, содержимое которого читается почти как обычный английский текст, но требует строгого порядка команд . Типичный набор инструкций включает:

После написания инструкций выполняется сборка образа командой docker build -t [имя_образа] ., где флаг -t задает тег (имя), а точка указывает на текущую директорию . Когда образ готов, он появляется в списке доступных в системе, и его можно запустить в работу .

Запуск контейнера осуществляется командой docker run. Важно использовать флаг -d (detached mode), чтобы приложение работало в фоновом режиме, и флаг -p, который пробрасывает порты . Например, маппинг 127.0.0.1:3000:3000 позволяет обращаться к приложению внутри контейнера через локальный браузер по адресу localhost:3000 . Если код приложения меняется, цикл повторяется: старый контейнер удаляется (командой docker rm -f [id]), образ пересобирается, и запускается новый контейнер . Ранее в разговоре Джастин упоминал, что в реальных проектах данные должны сохраняться даже после удаления контейнера, но детально механизмы персистентности и сетевого взаимодействия между несколькими контейнерами (например, приложением и базой данных SQL) будут разобраны в следующих частях курса .

🛠️ Оркестрация и персистентность: работа с Docker Compose 25:08

Магия Docker Compose: один конфиг для всей системы 25:49

Работа с отдельными контейнерами вручную требует ввода длинных команд в терминале, что становится неудобным при усложнении архитектуры . Для решения этой проблемы используется Docker Compose — инструмент, позволяющий описывать и запускать многоконтейнерные приложения с помощью одного конфигурационного файла . Вместо того чтобы запускать отдельно базу данных и отдельно приложение, разработчик создает файл compose.yaml (или docker-compose.yml), который автоматизирует весь процесс .

При написании Compose-файла критически важна структура и отступы, так как формат YAML крайне строг к синтаксису . Основные элементы конфигурации включают в себя:

Docker Compose значительно упрощает сетевое взаимодействие: контейнеры, описанные в одном файле, по умолчанию находятся в одной сети и могут легко обращаться друг к другу . Для запуска всей инфраструктуры достаточно выполнить команду docker compose up, а добавление флага -d (detached mode) позволит запустить процессы в фоновом режиме, не блокируя терминал . Если же работу нужно прекратить, команда docker compose down не только остановит, но и корректно удалит созданные контейнеры .

Персистентность данных: как не потерять базу при перезапуске 25:21

Одной из главных проблем контейнеризации является эфемерность: по умолчанию все данные внутри контейнера стираются после его удаления. Чтобы данные в базе данных MySQL или Postgres сохранялись, используются Docker-тома (volumes) . В интерфейсе приложения это подтверждается тем, что задачи, созданные в To-Do приложении, корректно отображаются в базе данных даже после манипуляций с контейнерами .

При использовании Docker Compose тома описываются на двух уровнях. Сначала конкретный сервис (например, MySQL) указывает путь внутри контейнера, который нужно синхронизировать, а затем на верхнем уровне файла объявляется именованный том, такой как todo-mysql-data . Это гарантирует, что даже если разработчик полностью удалит контейнер с базой данных, при следующем запуске информация останется нетронутой . Ранее в курсе уже упоминалось, что использование томов является фундаментом для работы с любыми системами хранения данных в Docker .

Такой подход позволяет создать надежную среду для разработки. Если у вас есть коллеги, им достаточно получить ваш образ и файл Compose, чтобы развернуть идентичную среду со всеми зависимостями и переменными окружения . Это исключает классическую проблему «на моей машине всё работает», позволяя всей команде использовать одинаковые версии инструментов и библиотек .

Подготовка инфраструктуры для работы с SQL 31:02

После освоения основ Docker следующим логическим шагом становится настройка среды для работы с языком структурированных запросов (SQL). Вместо локальной установки тяжеловесных СУБД, таких как PostgreSQL, в современной практике Data Engineering используется запуск базы внутри контейнера . Процесс подготовки «песочницы» начинается с загрузки образа командой docker pull postgres, которая скачивает последнюю версию из Docker Hub .

Для запуска контейнера с Postgres используются специфические переменные окружения, в частности POSTGRES_PASSWORD, без которой база данных не запустится . Автор демонстрирует создание контейнера с именем data-engineering-postgres и паролем secret . Важно понимать разницу между запущенным контейнером и конкретной базой данных внутри него: для создания новой БД используется команда docker exec с утилитой createDB .

Такая установка позволяет мгновенно подключиться к терминалу базы данных через команду psql . На этом этапе завершается инфраструктурная часть: теперь у инженера есть готовая, изолированная среда, где можно создавать таблицы (например, users или films) и наполнять их тестовыми данными [33:45, 40:07]. В дальнейшем обучении этот фундамент Docker позволит переходить к изучению синтаксиса SQL, включая выборку данных через SELECT, обновление записей через UPDATE и агрегацию информации, что является базовыми навыками для любого аналитика или инженера данных [35:01, 37:22, 44:03].

📊 Глава 3. Практика SQL: от базовой выборки к управлению данными 50:23

Базовые операции CRUD: создание и наполнение таблиц 51:19

В работе дата-инженера умение манипулировать данными на базовом уровне предшествует любой сложной аналитике. Основной фокус в этой части курса смещается на практическое применение команд INSERT и SELECT для управления наборами данных . Чтобы продемонстрировать связи между сущностями, инструктор создает две новые таблицы: actors (актеры) с полями actor_id и actor_name, а также связующую таблицу film_actors . Процесс наполнения данными (INSERT) показан на примере сопоставления имен актеров с конкретными фильмами, которые уже есть в базе .

Для проверки корректности вставки используется стандартная выборка SELECT *, которая позволяет мгновенно увидеть структуру: например, что в таблице actors каждому имени присвоен уникальный числовой идентификатор . Важность команды SELECT подчеркивается при работе с таблицей Filmore category, где после выполнения запроса отображается 39 записей, содержащих ID категорий и ID фильмов .

В процессе обучения рассматриваются сценарии изменения состояния базы данных:

Эти базовые манипуляции (часть цикла CRUD) критически важны для понимания того, как данные будут вести себя на следующих этапах — при объединении таблиц или их трансформации, о чем пойдет речь в будущих главах .

Псевдонимы (Aliases) и форматирование результатов выборки 52:39

По мере усложнения запросов, когда в выборке участвуют несколько таблиц, SQL-код может стать громоздким. Для решения этой проблемы вводятся псевдонимы (Aliases) . Инструктор демонстрирует, как присвоить таблице films короткое имя f, а таблице actorsa . Это позволяет обращаться к столбцам через точечную нотацию, например f.title или a.actor_name, что значительно упрощает чтение кода .

Особое внимание уделяется оператору AS, который используется для переименования столбцов в итоговой таблице результатов . Хотя технически этот оператор является необязательным и его можно опустить, его использование делает намерения инженера более прозрачными: например, запрос Select title AS name превратит заголовок колонки «title» в «name» в выводе .

Для организации данных в удобном для анализа виде применяется оператор ORDER BY . В примерах курса данные сортируются:

  1. По числовым значениям: например, по film_id в возрастающем порядке (1, 2, 3...), чтобы «Inception» (ID 1) всегда шел первым .
  2. По алфавиту: при объединении списков имен актеров и названий фильмов через оператор UNION (подробно изучаемый позже), итоговый результат выстраивается в алфавитном порядке .

Инструктор подчеркивает, что правильное форматирование и использование псевдонимов — это не просто вопрос эстетики, а необходимый навык для подготовки «чистых» таблиц, которые затем будут использоваться командами аналитиков .

Логика фильтрации и подготовка к агрегации данных 1:04:08

Хотя агрегатные функции (такие как COUNT, SUM, AVG, MAX/MIN) и оператор GROUP BY были впервые упомянуты ранее , в данном сегменте акцент делается на логике подготовки данных для таких вычислений. Ключевым инструментом здесь выступает фильтрация через предложение WHERE в сочетании с оператором IN .

Инструктор показывает, как извлечь из базы только те фильмы, в которых снимались конкретные люди, например Леонардо Ди Каприо или Том Хэнкс . Этот запрос возвращает список из трех картин: «Inception», «Forrest Gump» и «Toy Story» . Подобная фильтрация является фундаментом для агрегации: прежде чем посчитать средний бюджет или количество фильмов (COUNT), инженер должен точно определить выборку данных.

В ходе демонстрации также упоминаются важные аспекты работы с данными:

Эти навыки работы с выборкой и условиями подготавливают почву для создания полноценного ETL-скрипта на Python . Ранее в курсе уже затрагивались основы Docker, и теперь эти SQL-знания станут основой для данных, которые будут циркулировать между контейнерами источника и назначения в рамках создаваемого конвейера .

🧩 Объединение данных и сложные выборки: SQL в сердце трансформаций 1:15:14

После того как инфраструктура данных настроена через Docker (о чем подробно говорилось в предыдущих частях), наступает критический момент: данные нужно не просто переместить, а сделать их пригодными для анализа . Простой перенос таблиц «как есть» редко удовлетворяет запросам бизнеса. В этой главе мы разберем, как использовать мощь SQL для объединения разрозненных сущностей и создания сложных выборок, которые превратят сырые строки в структурированные инсайты.

Искусство объединения: JOIN и работа с промежуточными таблицами 1:31:50

Основная задача инженера данных при работе с реляционными базами — это восстановление связей между таблицами. В нашем проекте используются три ключевые сущности: actors (актеры), films (фильмы) и связующая таблица film_actors . Поскольку один актер может сниматься в разных фильмах, а в одном фильме участвует множество актеров, мы имеем дело со связью «многие ко многим», которая реализуется через промежуточную таблицу-связку .

Для извлечения осмысленной информации используются следующие типы соединений:

Как отмечает автор курса, часто аналитики или специалисты по Data Science не хотят писать сложные SQL-запросы самостоятельно . Задача инженера данных — заранее подготовить эти объединения, чтобы в целевой базе (destination database) данные лежали в уже «сшитом» и понятном виде .

Подзапросы и оператор UNION: гибкость в подготовке данных 1:38:47

Когда простых JOIN-ов недостаточно для «морфинга» данных под конкретные нужды бизнеса , в игру вступают подзапросы и операторы объединения результатов.

Подзапросы позволяют изолировать часть логики. Например, мы можем сначала отфильтровать список только «топовых» актеров во внутреннем запросе, а затем уже во внешнем запросе объединять этот результат с таблицей фильмов . Это повышает читаемость кода и позволяет строить многоуровневые трансформации, превращая сырые данные в так называемые «витрины данных».

Оператор UNION незаменим в ситуациях, когда данные об однотипных сущностях приходят из разных источников. В контексте нашего ELT-процесса это может выглядеть так:

  1. У нас есть таблица актеров из одной системы и аналогичная таблица из другой.
  2. Чтобы создать единый мастер-список для аналитиков, мы используем UNION, который «склеивает» результаты двух выборок по вертикали .
  3. Важно помнить, что для работы UNION количество и типы колонок в объединяемых запросах должны строго совпадать .

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

Инфраструктура для трансформаций: подготовка к dbt 1:31:38

Для автоматизации всех описанных SQL-операций (Joins, Subqueries, Unions) автор предлагает использовать dbt (Data Build Tool) . Это open-source инструмент, который позволяет писать SQL-код в виде моделей. Вместо того чтобы вручную запускать скрипты объединения таблиц, dbt берет на себя управление зависимостями .

Процесс подготовки включает несколько этапов:

Такой подход превращает написание SQL-запросов из хаотичного процесса в стройную систему разработки, где каждая трансформация — это отдельная, тестируемая модель . После успешного запуска ELT-скрипта и подтверждения наличия данных в базе через psql , мы готовы к созданию полноценных аналитических моделей.

🛠️ Развертывание ETL-пайплайна: интеграция Python-скрипта и Docker 1:40:19

Проектирование логики трансформации данных 1:42:14

После того как первичные данные были подготовлены, необходимо определить логику их преобразования внутри пайплайна. На этом этапе создаются кастомные модели, которые формулируют и модифицируют сырые данные в таблицы нужного формата . Одной из ключевых задач становится объединение информации о фильмах и актерах в единую структуру, ориентированную на рейтинги .

Для написания чистого и поддерживаемого кода используются обобщенные табличные выражения (CTE — Common Table Expressions) . Это позволяет оборачивать подзапросы в именованные блоки, которые действуют только в рамках одного файла, что значительно упрощает чтение сложных SQL-конструкций . В процессе трансформации применяется оператор CASE (аналог if-else в программировании) для сегментации пользовательских рейтингов: например, оценки выше 4.5 классифицируются как «Excellent», а выше 4.0 — как «Good» .

Технически процесс объединения данных выглядит следующим образом:

Такой подход позволяет подготовить данные к аналитике еще на этапе загрузки, минимизируя нагрузку на базу при последующих запросах .

Настройка Docker-окружения для ETL-пайплайна 1:48:04

Для автоматизации работы ETL-скрипта требуется правильно настроенная контейнеризация. В файле docker-compose.yaml описываются сервисы, которые будут отвечать за обработку данных . Основным звеном здесь выступает Python-скрипт (ранее упоминавшийся как скрипт на базе subprocess), который выполняет дамп и загрузку между базами Postgres, но теперь к нему добавляется сервисный слой для трансформаций .

Ключевым моментом в конфигурации Docker является управление зависимостями через параметр depends_on . Трансформационная часть пайплайна должна запускаться только после того, как Python-скрипт (elt_script) успешно завершит свою работу . Если запустить процесс обработки на пустой базе, система выдаст ошибку, так как ей не к чему будет обращаться .

Важные аспекты настройки контейнера:

  1. Образы и версии: Использование специфических образов для работы с Postgres (например, dbt-postgres версии 1.4.7) .
  2. Маппинг томов (Volumes): Необходимо сопоставить локальные директории проекта с путями внутри контейнера, чтобы Docker «видел» ваши SQL-файлы и профили подключения .
  3. Переменные окружения: Установка целевых таргетов (например, dev для разработки) позволяет гибко переключаться между тестовыми и боевыми средами .
  4. Сетевое взаимодействие: Все компоненты, включая базы данных и скрипты, должны находиться в одной сети (elt_network), чтобы иметь возможность беспрепятственно обмениваться данными .

При настройке важно избегать опечаток в именах директорий и файлов (например, использование подчеркивания вместо тире), так как Docker чувствителен к путям .

Отладка и верификация данных в целевой базе Postgres 1:54:48

После запуска контейнеров через docker-compose up критически важно убедиться, что данные прошли весь путь от источника до финальной таблицы без потерь . Первым признаком успеха является статус Exited Code 0 у ETL-скрипта, что означает корректное завершение процесса выгрузки и загрузки данных .

Для проверки результатов используется терминал и команда docker exec . Процесс верификации включает:

Если все этапы выполнены верно, в списке появится новая таблица (например, film_ratings), созданная в результате работы пайплайна . Выполнив простой SQL-запрос SELECT * FROM film_ratings, можно увидеть результат трансформации: объединенные данные о фильмах, списки актеров и присвоенные категории рейтингов . Успешное отображение таких фильмов, как «Inception» с Леонардо Ди Каприо и его категорией рейтинга, подтверждает работоспособность всей логики .

Ранее в разговоре авторы упоминали возможность сделать эти запросы более гибкими. В дальнейшем для улучшения читаемости и повторного использования кода будут применяться более продвинутые методы, такие как макросы и Jinja-шаблоны , а также системы оркестрации вроде Apache Airflow для замены ручного запуска и Cron-задач .

🛠️ Трансформации и логика dbt: от SQL-моделей до динамических макросов 2:05:23

После того как первичные данные загружены в хранилище, наступает этап их преобразования. В современной дата-инженерии для этого чаще всего используется dbt (data build tool) — инструмент, который позволяет описывать логику трансформаций на чистом SQL, сохраняя при этом все преимущества профессиональной разработки: версионирование, тестирование и документацию . В отличие от традиционных ETL-инструментов, dbt реализует подход ELT, где трансформации происходят непосредственно внутри целевой базы данных, используя её вычислительные мощности .

Модели dbt и концепция трансформаций «внутри» базы 2:09:32

Основным строительным блоком в dbt является «модель». По сути, это обычный файл .sql, содержащий инструкцию SELECT . Когда инженер запускает команду dbt run, инструмент автоматически оборачивает этот запрос в конструкцию CREATE TABLE AS... или CREATE VIEW..., создавая готовые объекты в базе данных . Это избавляет разработчика от необходимости вручную писать DDL-коды (Data Definition Language) и следить за порядком создания таблиц.

В рамках проекта трансформации организуются в специальной папке (например, custom_postgres), которая затем монтируется в рабочее окружение . Это позволяет dbt иметь полный доступ к исходным кодам моделей и конфигурационным файлам проекта . Важно понимать, что dbt не перемещает данные между системами; он лишь отправляет SQL-команды в Postgres, заставляя базу данных эффективно преобразовывать уже имеющиеся в ней «сырые» таблицы в аналитические витрины .

Для работы dbt в контейнеризированной среде используется специализированный образ, например ghcr.io/dbt-labs/dbt-postgres версии 1.4.7 . При запуске трансформаций критически важно правильно указать пути к проекту:

Такое разделение позволяет хранить логику трансформаций отдельно от учетных данных для доступа к базе .

Гибкость кода: Jinja-шаблоны и макросы в dbt 2:16:24

Одной из самых мощных функций dbt является использование движка шаблонов Jinja. Хотя dbt и работает с SQL, Jinja превращает его в подобие языка программирования, позволяя использовать переменные, циклы и условия прямо внутри запросов . Это критично для создания динамических моделей, которые адаптируются к входным данным без переписывания кода вручную.

Макросы в dbt — это переиспользуемые фрагменты кода, аналогичные функциям в Python . Если у инженера есть сложная логика очистки данных или специфический расчет, который повторяется в десяти моделях, он может вынести его в макрос и вызывать одной строкой . Это не только сокращает объем кода, но и радикально упрощает его поддержку: ошибка исправляется в одном месте, а не в десяти .

Применение Jinja также позволяет реализовать механизм ссылок {{ ref('model_name') }}. Вместо того чтобы жестко прописывать имена таблиц в SQL (например, FROM raw_data.users), инженер пишет ссылку на модель . dbt на лету выстраивает граф зависимостей (Lineage Graph), понимая, какие таблицы нужно создать сначала, а какие — после, чтобы данные в финальных отчетах всегда были актуальными . Ранее в разговоре авторы упоминали, что такая автоматизация зависимостей — ключевое отличие dbt от простых SQL-скриптов, запускаемых вручную.

Интеграция и конфигурация dbt в производственном цикле 2:16:32

Для того чтобы dbt успешно взаимодействовал с базой данных в рамках автоматизированного пайплайна, необходимо обеспечить правильное мапирование томов и настройку профилей. В конфигурации системы папка с трансформациями custom_postgres связывается с внутренней директорией /dbt внутри рабочего контейнера . Аналогичным образом пробрасываются и настройки подключений через profiles.yml, чтобы инструмент знал адрес хоста, порт и учетные данные базы данных .

В процессе работы dbt может быть настроен на автоматическое удаление временных контейнеров после выполнения задачи (Auto remove = true), что позволяет экономить системные ресурсы . При этом взаимодействие с Docker-сетью происходит через специальный сокет unix:///var/run/docker.sock, что дает инструментам возможность «общаться» друг с другом внутри изолированной среды .

Основные этапы настройки dbt для продакшена включают:

  1. Определение сетевого режима (например, bridge), соответствующего драйверу общей сети проекта .
  2. Монтирование исходного кода моделей в целевой контейнер через type=bind .
  3. Настройку зависимостей между задачами: сначала должна завершиться загрузка данных (инструментами, описанными в предыдущих главах), и только потом запускается dbt run .

Такой подход гарантирует, что трансформации всегда работают с полным набором данных, а логика SQL-моделей остается чистой и независимой от инфраструктурного кода .

🐘 Оркестрация процессов через Apache Airflow

Настройка DAG для управления ETL и dbt 2:30:45

Когда основные компоненты ETL-скрипта и dbt-модели готовы, наступает этап их объединения в единый автоматизированный рабочий процесс. Для этого используется Apache Airflow, где логика управления описывается в виде DAG (Directed Acyclic Graph) . В рассматриваемом примере первый оператор отвечает за запуск Python-скрипта, а второй — DockerOperator — создает отдельный контейнер для dbt . Это позволяет изолированно запустить трансформации поверх данных, уже загруженных в целевое хранилище на первом этапе .

Важным архитектурным изменением становится модификация файла docker-compose.yaml. Поскольку теперь запуском задач управляет Airflow, из основного файла конфигурации Docker следует закомментировать сервисы elt_script и dbt . Airflow сам будет инициировать создание нужных контейнеров в нужной последовательности . Перед полноценным запуском всей системы критически важно выполнить команду docker compose up init-airflow . Это инициализирует базу данных Postgres для метаданных Airflow и настраивает необходимые учетные записи . Только после того как контейнеры базы данных и инициализации перейдут в статус выполнения, можно запускать веб-сервер и планировщик (scheduler) .

Отладка и работа с интерфейсом Airflow 2:33:13

Веб-интерфейс Airflow доступен по адресу localhost:8080 . Стандартные учетные данные для входа в рамках данного проекта — airflow / airflow . Часто при первом запуске возникают ошибки импорта, такие как "broken DAG" . В процессе разработки автор сталкивается с типичной опечаткой в названии модулей: вместо operators необходимо использовать providers в пути импорта для Docker-оператора . Правильный путь выглядит как airflow.providers.docker.operators.docker .

После исправления синтаксических ошибок в UI появляется DAG с именем elt_and_dbt . При ручном запуске графа (trigger dag) можно наблюдать за статусом выполнения каждой задачи в реальном времени . Если задача dbt падает с ошибкой, Airflow предоставляет доступ к подробным логам, которые хранятся в его собственной базе данных Postgres . Одной из специфических проблем при использовании Docker внутри Airflow является настройка путей: проект dbt должен быть правильно смонтирован, например, по пути /opt/dbt внутри контейнера . Также следует внимательно следить за тем, чтобы в папке моделей не оставалось лишних примеров (вроде my_second_dbt_model.sql), которые могут вызвать конфликты при компиляции проекта . Успешное выполнение обеих задач в DAG подтверждается зеленым цветом индикаторов в интерфейсе .

Автоматизация среды и переход к новым операторам 2:43:35

Для масштабирования проекта и добавления новых инструментов, таких как Airbyte (платформа для интеграции данных), необходимо расширить возможности контейнера Airflow. В Dockerfile добавляются новые провайдеры через pip install: помимо Docker-провайдера, устанавливаются apache-airflow-providers-http и apache-airflow-providers-airbyte . HTTP-провайдер является обязательной зависимостью для работы с Airbyte . Чтобы упростить процесс запуска множества контейнеров, автор создает вспомогательные bash-скрипты: start.sh и stop.sh . Скрипт запуска автоматизирует инициализацию Airflow, ожидание в 5 секунд и последующий запуск Airbyte из его собственной директории .

В самом коде DAG также происходят изменения. Вместо использования Python-оператора для самописного ETL-скрипта (который ранее обсуждался в контексте извлечения данных), внедряется AirbyteTriggerSyncOperator . Этот оператор позволяет инициировать синхронизацию данных через внешний инструмент, передавая лишь connection_id . Основные параметры оператора включают:

Подготовка инфраструктуры для внешних инструментов 2:51:30

Интеграция сторонних инструментов в оркестрацию требует понимания того, как контейнеры взаимодействуют друг с другом. Поскольку Airbyte работает в своем наборе Docker-контейнеров, Airflow должен знать, как к ним обратиться . Для этого в настройках подключений Airflow используется адрес host.docker.internal, что позволяет контейнерам «общаться» через хост-машину . При настройке источников данных (например, Source Postgres) важно правильно указывать порты, такие как 5433 для исходной базы, чтобы избежать конфликтов с целевой базой данных .

Хотя Airbyte имеет собственный планировщик, при работе в связке с Airflow его лучше переключить в режим manual . Это гарантирует, что именно Airflow будет выступать «единым источником истины» для расписания всех процессов . Выбор режима синхронизации (например, Full Refresh Overwrite ) также влияет на то, как dbt-модели будут обрабатывать данные на следующем шаге DAG. Таким образом, Airflow связывает разрозненные инструменты — от систем перемещения данных до систем трансформации — в единый, контролируемый поток данных.

🔄 Интеграция с Airbyte: Переход к современному стеку данных 2:55:40

В финальной стадии проекта происходит качественный переход от самописных решений к профессиональным инструментам автоматизации. Если ранее в рамках курса мы создавали ETL-скрипт на Python вручную, то теперь его место занимает Airbyte — платформа с открытым исходным кодом, которая стандартизирует процесс извлечения и загрузки данных. Этот этап превращает разрозненные контейнеры в согласованную экосистему, где каждый инструмент выполняет свою узкоспециализированную задачу.

Синхронизация Airflow и Airbyte: Настройка соединений 2:55:55

Первым шагом к автоматизации является установление связи между оркестратором Airflow и платформой Airbyte. Для этого необходимо получить уникальный идентификатор соединения (Connection ID) непосредственно из интерфейса Airbyte и интегрировать его в код нашего DAG-файла . Это критически важный момент, так как именно через этот ID Airflow будет отдавать команды на запуск конкретных потоков данных.

Однако простого обновления кода недостаточно. Поскольку компоненты системы работают в изолированных Docker-контейнерах, изменения не всегда распространяются мгновенно . Инструктор подчеркивает, что для корректной работы часто требуется перезапуск части инфраструктуры. В данном случае необходимо остановить секцию ELT, сохранив Airbyte запущенным, а затем инициализировать процесс заново с помощью скрипта elt.sh . Это гарантирует, что все переменные окружения и обновленные DAG-файлы будут подтянуты системой корректно .

Настройка самого соединения внутри веб-интерфейса Airflow требует точности в деталях:

Устранение неполадок при развертывании в Docker 2:57:26

Интеграция сложных инструментов часто сопровождается техническими трудностями, связанными с зависимостями и правами доступа. В процессе настройки автор сталкивается с ошибкой импорта оператора airflow.providers.airbyte.operators.airbyte . Проблема кроется в специфике сборки образов: Airflow требует выполнения установки провайдеров от имени определенного пользователя, что создает конфликт при стандартной сборке .

Решение заключается в специфическом алгоритме: сначала система должна войти под пользователем airflow для установки необходимых операторов, а затем переключиться на пользователя root для выполнения DAG . Еще один важный нюанс — кеширование образов в Docker. Если изменения в командах установки не применяются, единственный надежный способ — полностью удалить старые образы веб-сервера и планировщика (scheduler), после чего запустить сборку с нуля . Только после такой «чистой» переустановки DAG появляется в веб-интерфейсе без ошибок .

Запуск финального пайплайна и верификация данных 3:00:29

Когда все настройки завершены, происходит запуск всей цепочки. Airflow триггерит Airbyte, и в интерфейсе последнего можно наблюдать за процессом синхронизации в реальном времени . Успешное завершение этого этапа подтверждается статистикой: в рассматриваемом примере из источника было извлечено 1113 записей . Сразу после этого оркестратор автоматически запускает dbt (о котором рассказывалось в предыдущих главах), чтобы выполнить финальные трансформации .

Проверка результата в целевой базе данных (destination_db) показывает полную картину работы пайплайна:

  1. Появляются таблицы с префиксом _airbyte_raw, содержащие «сырые» данные и метаданные платформы .
  2. Присутствуют финальные таблицы, созданные dbt, такие как specific_movie .
  3. Данные успешно перемещены из Postgres (источник) через Airbyte в целевую БД и трансформированы для анализа .

В итоге проект демонстрирует эволюцию пайплайна: от сложного и хрупкого ручного скрипта в начале обучения к чистому и масштабируемому решению на базе Modern Data Stack . Использование Airbyte и Airflow позволяет инженеру сосредоточиться на логике данных, а не на написании кода для обработки API или сетевых протоколов .

💬 Цитаты

«85-87% проектов в сфере Big Data терпят неудачу из-за ненадежной инфраструктуры.»

«Docker compose is a tool that helps you to find and share multiple container applications and makes this whole process 10 times easier.»

«Мы можем использовать DBT для создания кастомных моделей... чтобы данные были структурированы именно так, как нужно аналитикам.»

«CTE (Common Table Expression) — это как обертка для запроса, которая делает код поддерживаемым и ограниченным по области видимости.»

«Я оставляю все эти ошибки в видео не потому, что это выглядит круто, а потому что ошибки — это часть инженерии.»

«Вы видите, как пайплайн может эволюционировать: насколько сложным он может быть в начале и каким простым становится в конце.»

👥 Спикер
📖 Термины
Docker
Платформа для разработки и запуска приложений в изолированных контейнерах.
dbt (data build tool)
Фреймворк для трансформации данных внутри хранилища с помощью SQL-запросов.
ETL
Процесс извлечения (Extract), преобразования (Transform) и загрузки (Load) данных.
Apache Airflow
Платформа для программного создания, планирования и мониторинга рабочих процессов (workflow).
Airbyte
Платформа с открытым исходным кодом для интеграции данных из различных источников.
Технологии и IT Docker dbt Apache Airflow Airbyte SQL