3. Автоматизация ETL-процессов Flashcards
Принципы построения ETL
- Чистый код — хорошим тоном считается следовать правилам pep8
- Простота — старайтесь писать читаемый и лаконичный код.
- Единообразие — необходимо стремиться к единым принципам построения ваших дата-пайплайнов.
- Время выполнения пайплайна — необходимо следить за SLA, например, ежедневный процесс не должен выполняться более суток.
- Меньше сетевого трафика — используйте только необходимые данные, не перегружая систему. В данном случае можем заметить преимущество ELT — данные выгружаются в хранилище один раз, а при использовании ETL — минимум два раза.
- Работа с репликой — используйте только реплики источников для предотвращения неожиданных падений систем/баз данных/др.
- Оптимизация забора данных — пользуйтесь индексами, пишите оптимальные запросы, старайтесь оптимизировать ваш дата-пайплайн.
Способы загрузки данных (SCD) — ориентируйтесь на количество данных, чтобы принять решение о применении инкрементальной загрузки. - Партицирование — при возможности используйте партиции.
- Инкрементальный пересчет витрин — стоит пересчитывать только новые данные витрины.
- Загрузка всего без ограничений — нормально получать все данные в большинстве случаев.
- Избавляться от неактуального — периодически проводите аудит вашего хранилища, чтобы не перегрузить его.
- Идемподентность — (свойство при повторном запуске выдавать точно такой же результат, как при первом запуске) — отдавайте предпочтение merge перед insert для избежания возникновения дубликатов.
- Аудиторский след — стоит хранить данные, такие как в источниках.
Преимущества Airflow
> Open source
> Отличная документация
> Простой код на Питоне
> Удобный веб-интерфейс
> Алертинг и мониторинг
> Интеграция с основными источниками
> Кастомизация
> Масштабирование
> Большое комьюнити
DAG
(определение, из чего состоит)
DAG (Directed Acyclic Graph) — направленный ацикличный граф. Это граф, в котором нет зацикливания. В нем могут быть разветвления, но в конце они сходятся в одной точке.
Вершины в DAG — это отдельные задачи (task).
Ребра в DAG — зависимости между задачами.
DAG-ов в Airflow может быть несчетное количество.
Task (определение, какие бывают)
Задача (task) — это одна из двух сущностей:
> сенсор. Они используются, когда нам нужно дождаться наступления какого-то события, например, появление строчки в БД, наступление определенного времени, появление файла в s3.
> оператор. Это действие, которое выполняет конкретная задача, например, забирает данные из базы, отсылает письма, вычитывает данные из API, производит вычисления.
Задачи объединяются в DAG по смыслу.
Процесс выполнения задач
Сначала запускаются таски, которые не имеют предшественников. После того, как такие задачи отработали, запускаются зависимые от них таски. Это продолжается, пока мы не дойдем до конца DAG, то есть пока все задачи не будут обработаны.
Если при выполнении задача упала, то она переходит в состояние retry и через определенное время (по умолчанию 10 минут) перезапускается. Если после 3-х (этот параметр тоже настраивается) перезапусков таск так и не смог выполниться успешно, то он переводится в состояние failed. Все последующие за ним задачи переводятся в состояние upstream failed и выполнены не будут. В таком случае DAG переходит в состояние failed.
Компоненты Airflow
> Web Server Airflow
Sheduler
Executor
Worker
Metadata Database
Web Server Airflow
отвечает за пользовательский интерфейс и дает возможность контролировать пайплайны.
Основные задачи:
* Внешний вид DAG-a
* Статус выполнения (их получает из метаданных Airflow)
* Перезапуск (как тасок, так и DAG-ов)
* Отладка
Sheduler
планировщик.
- Анализирует DAG’и (ищет те, которые готовы к запуску)
- Создает DAG Run с конкретным execution_date
- Создает Task Instance
- Ставит таски в очередь
DAG Run — это экземпляр DAG-а. Каждый экземпляр характеризуется параметром execution_date (начало предыдущего периода).
Task Instance — это экземпляр задачи. Инстансы привязываются к DAG. У них так же определен параметр execution_date.
Executor
механизм, с помощью которого запускаются экземпляры задач. Он работает в связке с планировщиком.
Executor-ы делятся на две категории:
* локальные — исполняются на той же машине, на которой есть планировщик
- нелокальные — могут запускать таски удаленно
Локальные Executor
- SequentialExecutor - Последовательный запуск задач;
- LocalExecutor (По дочернему процессу на задачу);
- DebugExecutor (Для запуска и отладки из IDE)
Нелокальные Executor
- CeleryExecutor - Требует брокер сообщений. Несколько серверов с воркерами
- DaskExecutor - Использует Dask
- KubernetesExecutor - Новый pod для каждого task instance
- CeleryKubernetesExecutor - CeleryExecutor/KubernetesExecutor
- Custom - Самописаный
Worker
процесс, в котором исполняются задачи. В зависимости от executor-a он может быть размещен локально (на той же машине, что и планировщик), либо на отдельно машине/машинах
Metadata Database
база метаданных. В ней хранится информация о состоянии всех пайплайнов:
* DAG (абстрактные DAG-и)
- DAG Run (конкретные инстансы DAG-ов)
- Task Instance
- Variable (глобальные переменные Airflow)
- Connection
- Xcom
…
Пул
У executor-ов есть ограниченное количество воркеров. Если запущен некий не самый важные DAG, который генерирует слишком много задач одновременно, то такому DAG-у нужно ограничить ресурсы с помощью пулов, чтобы другие DAG-и так же могли запускаться.
Пул — это абстрактное ограничение на количество одновременно выполняемых задач.
Каждый пул имеет ограничение по количеству слотов — количество задач, которые одновременно могут быть запущены в пуле.
Способы создания DAG (код)
- dag = DAG(аргументы)
Самый простой вариант. Создание переменной класса DAG. В данном случае каждому таску надо обязательно привязываться к DAG’у. И внутри каждого таска явно указывать на DAG. - with DAG(аргументы) as dag:
таски без указания DAG
Он аналогичен первому варианту, но производится через контекстный менеджер. Здесь DAG не нужно указывать внутри каждого таска, он назначается им автоматически. - Этот вариант появился в Airflow2. DAG создается с помощью декоратора @dag. Нам требуется создать функцию со списком тасков внутри и обернуть ее в декоратор. Таким образом мы получаем переменную класса DAG. Эту переменную мы объявляем в глобальной области видимости, с помощью чего Airflow понимает, что внутри скрипта находится DAG.