Wprowadzenie
Podstawowa architektura
Do podstawowych elementów Apache Airflow (rysunek 0.1) należą:
Scheduler - planuje kolejność wykonywania zadań. Otrzymuje również informacje o ich statusach.
Worker - na nim są wykonywane zadania otrzymane od schedulera. W klastrze Apache Airflow może być więcej niż jeden worker. Innymi słowy: jest to przestrzeń/środowisko dla zadań.
Executor - często jest elementem schedulera, ponieważ to scheduler zleca wykonanie zadań na elemencie worker.
Webserver - interfejs graficzny pozwalający na zarządzanie Apache Airflow. To on stanowi podstawową komunikację z użytkownikiem.
DAG Directory - miejsce, w którym przechowujemy DAG-i (
Directed Acyclic Graph). W ramach niego planujemy zadania oraz kolejność ich wykonywania. Co najważniejsze, Apache Airflow traktuje DAG jak obiekt, więc każde uruchomienie DAG-a będzie powodowało utworzenie instancji. Więcej szczegółów w kolejnych rozdziałach.
Metadata Database - baza danych (PostgreSQL, MySQL lub sqlite) do przechowywania metadanych: zmienne, połączenia, stany zadań itd.
Rysunek 0.1. Podstawowa architektura Apache Airflow
Bardziej szczegółowe architektury poznasz w rozdziale 10., "Symulacja środowiska HA", w którym utworzysz środowisko typu HA (High Availability).
Przygotowanie środowiska pracy
Wymagania
Na początku trzeba zaznaczyć, że pomyślna konfiguracja Apache Airflow może zostać przeprowadzona jedynie na systemach operacyjnych z rodziny Linux lub macOS. Jeżeli pracujesz w systemie Windows, rekomendowana jest instalacja Linuksa (nawet na maszynie wirtualnej) lub wykorzystanie konteneryzacji za pomocą Dockera lub Podmana. Dodatkowo należy zainstalować wspieraną wersję Pythona. Na czas tworzenia książki Apache Airflow wspiera Pythona od wersji 3.8.
Do przygotowania naszego środowiska pracy będziemy potrzebowali:
systemu macOS lub Linux (Linux może być jako maszyna wirtualna lub kontener), Pythona w wersji 3.12.x, bazy danych PostgreSQL w wersji 13 lub nowszej (ja korzystam z 16.8).
Apache Airflow można uruchomić za pomocą WSL2 w systemie Windows, ale to rozwiązanie nie jest wspierane przez twórców i bywa rzadko wykorzystywane.
Instalacja modułów i zależności
Przejdźmy do instalacji niezbędnych bibliotek. Na początku skonfigurujmy nasze środowisko pracy. W tym celu przygotujemy katalog o nazwie airflow-sandbox i utworzymy w nim środowisko wirtualne Pythona.
mkdir airflow-sandbox
cd airflow-sandbox
virtualenv venv
source venv/bin/activate
Teraz możemy przejść do instalacji Apache Airflow. Zgodnie z dokumentacją możemy zbudować całe narzędzie za pomocą źródła dostępnego na GitHubie lub wykorzystać gotowe pakiety z https://www.pypi.org. Rekomendowana jest druga opcja, w ramach której należy wykonać polecenie:
pip install apache-airflow==2.10.5
Apache Airflow ma tak dużo zależności i dodatkowych rozszerzeń (providers), że rekomendowana jest instalacja ze wskazaniem ograniczeń za pomocą opcji -constraints. W dokumentacji znajdziemy link do listy ograniczeń dla każdej wersji Airflow. Jeżeli zatem chcemy wykonać "kompletną i poprawną instalację" dla naszej wersji Pythona, należy wykonać polecenie:
pip install apache-airflow==2.10.5 --constraint https://raw.githubusercontent.com/apache/airflow/constraints-2.10.0/constraints-3.12.txt
Niestety powyższe polecenia nie instalują wszystkich potrzebnych narzędzi i instalują tylko podstawowe dodatki (providers, o których będzie mowa w kolejnych rozdziałach). Jeżeli chcemy wykorzystać bazę danych MySQL lub PostgreSQL, będziemy potrzebować dodatkowych modułów, aby móc połączyć się z bazą danych. Dla bazy PostgreSQL należy zainstalować psycopg2-binary, a dla MySQL mysqlclient. Zależnie od wyboru bazy danych należy wykonać dodatkowo poniższe polecenia.
PostgreSQL:
pip install psycopg2-binary==2.9.10
MySQL:
pip install mysqlclient==2.2.7
Od tej pory w naszym środowisku wirtualnym Pythona mamy dostęp do polecenia/ narzędzia airflow.
Apache Airflow nie wspiera bazy MariaDB, pomimo jej podobieństw do MySQL-a.
Do materiałów zostały dołączone moduły oraz plik tekstowy z ograniczeniami, aby móc zainstalować je lokalnie z poziomu katalogu w trybie offline.
Inicjowanie środowiska
Aby uruchomić kompletne środowisko testowe oparte na sqlite, możemy wykonać polecenie airflow standalone i poczekać na uruchomienie wszystkich elementów narzędzia oraz otrzymać hasło do użytkownika admin. Jednak skupimy się na instalacji "krok po kroku" oraz różnicach w tym podejściu.
Na początku musimy zdefiniować katalog domowy Apache Airflow - u mnie będzie to /airflow. Robimy to za pomocą zmiennej środowiskowej AIRFLOW_HOME. We wskazanym katalogu będzie tworzona cała struktura orkiestratora. Wykonujemy w terminalu polecenie:
export AIRFLOW_HOME=ścieżka/do/katalogu/airflow
Teraz możemy zainicjować domyślną konfigurację za pomocą airflow db migrate. W naszym katalogu pojawią się nowe elementy:
Plik
airflow.cfg - konfiguracja, którą omówię w kolejnym kroku. Plik
airflow.db - baza sqlite, która jest domyślna dla Apache Airflow. Nie będzie nam ona potrzebna, ponieważ przełączymy się na MySQL/PostgreSQL. Katalog
logs - tutaj będą logowane operacje wykonywane przez elementy Apache Airflow.
Polecenie airflow db migrate wygeneruje komunikat podobny do tego z rysunku 0.2.
Rysunek 0.2. Wynik polecenia airflow db migrate
Przejdźmy teraz do pliku airflow.cfg. Plik jest obszerny, ponieważ domyślnie jest generowany wraz z komentarzami do zmiennych. Wiele atrybutów będzie omówionych w kolejnych rozdziałach, natomiast na ten moment warto przyjrzeć się poniższym:
dags_folder - tutaj będziemy umieszczać nasze DAG-i oraz ich elementy, np. skrypty SQL-a. Domyślnie jest to katalog
dags w katalogu domowym. default_timezone - domyślna strefa czasowa wykorzystywana przez Airflow. Wpływa ona na działanie większości elementów narzędzia, głównie na harmonogram wykonywania zadań. Co najważniejsze, wszystkie daty będą tłumaczone na strefę czasową ustawioną pod tą właśnie zmienną. Przykładowo: DAG utworzony dla strefy czasowej Europe/Amsterdam zostanie ustawiony na UTC. Rekomendowane jest wykorzystywanie UTC dla projektów w różnych strefach czasowych. Dla naszego środowiska do nauki możemy ustawić czas polski, czyli zmienić wartość na Europe/Warsaw. executor - kto będzie wykonywał nasze zadania w ramach orkiestracji. Domyślnie jest to SequentialExecutor, który wykonuje
wszystkie zadania w sposób sekwencyjny (jedno po drugim), dlatego jest on używany jedynie w środowiskach testowych. My będziemy korzystać na początku z LocalExecutor, ponieważ pozwoli nam on lokalnie wykonywać zadania w sposób równoległy. parallelism - odpowiada za to, ile zadań (ich instancji) w całym Apache Airflow może być uruchomionych jednocześnie. Przykładowo: jeśli mamy DAG zawierający trzy zadania i uruchomimy go cztery razy, powoduje to uruchomienie do 12 instancji zadań jednocześnie. U mnie będzie to wartość 12. max_active_tasks_per_dag - maksymalna liczba zadań aktywnych jednocześnie w DAG-u. Ustawiam wartość na 4. dags_are_paused_at_creation - powoduje, że nowo utworzony DAG nie zostanie automatycznie uruchomiony. Najlepiej jest zostawić domyślną wartość. max_active_runs_per_dag - maksymalna liczba uruchomionych instancji DAG-a (a nie zadań wewnątrz). Dla swojego środowiska ustawię wartość 8. load_examples - wartość True (domyślna) spowoduje załadowanie przykładowych DAG-ów. Rekomenduję ustawienie na False, aby mieć czyste środowisko pracy. dag_dir_list_interval - ustala w sekundach, jak często Airflow skanuje katalog z DAG-ami w poszukiwaniu nowych plików (nowych DAG-ów). Domyślnie jest to 5 minut (300), natomiast dla usprawnienia naszej nauki ustawimy 1 minutę (60). sql_alchemy_conn - definiuje połączenie do bazy danych. Domyślnie jest to sqlite w katalogu domowym Airflow. Natomiast nam zależy, aby połączyć się z MySQL-em lub PostgreSQL-em, by móc korzystać z LocalExecutor. Apache Airflow korzysta z SQLAlchemy do połączenia z bazą danych. Ja będę korzystał z bazy danych PostgreSQL.
Oto szablony dla zmiennej sql_alchemy_conn, jeżeli chcemy zamienić w konfiguracji bazę danych SQLite na PostgreSQL lub MySQL:
postgresql+psycopg2://<user>:<password>@<host>/<db>
mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
Przygotowanie bazy danych/uruchomienie Apache Airflow
Po wprowadzeniu powyższych zmian możemy załadować nową konfigurację. W tym celu na początku weryfikujemy, czy możemy połączyć się z bazą danych za pomocą polecenia airflow db check, a następnie ponownie wykonujemy airflow db migrate przy pomyślnym połączeniu z bazą. Poniżej możesz zauważyć, że teraz Apache Airflow łączy się z bazą PostgreSQL. Wyniki poleceń możemy zobaczyć na rysunku 0.3.
Rysunek 0.3. Wynik polecenia db migrate po podłączeniu do PostgreSQL-a
Możemy teraz przejść do utworzenia użytkownika. Robimy to w terminalu za pomocą polecenia:
airflow users create
Aby utworzyć administratora, wykonujemy polecenie w konsoli:
airflow users create \
--username admin \
password P4ssW0rd! \
firstname Piotr \
lastname Chudzik \
role Admin \
--email admin@acme.com
Jak widzimy, to polecenie zawiera kilka opcji. Aby je wykonać, musimy zdefiniować:
nazwę użytkownika (--username), początkowe hasło (--password), imię (--firstname), nazwisko (--lastname), adres e-mail (--email), rolę (--role).
Informacje dotyczące adresu e-mail czy nazwiska nie muszą być prawdziwe, natomiast najważniejsze są dane do logowania oraz rola użytkownika. Domyślnie Apache Airflow ma kilka wstępnie zdefiniowanych ról:
Admin - ma pełny dostęp do wszystkich funkcji Airflow, w tym zarządzania użytkownikami, konfiguracji systemu, edycji DAG-ów, uruchamiania i zatrzymywania zadań oraz przeglądania logów. User - standardowy użytkownik, który może przeglądać i uruchamiać DAG-i, ale nie ma dostępu do zarządzania użytkownikami ani konfiguracji systemu. Op - użytkownik z ograniczonymi uprawnieniami administracyjnymi, który może zarządzać działaniem DAG-ów, ale nie ma dostępu do konfiguracji systemu ani zarządzania użytkownikami. Viewer - użytkownik tylko do odczytu, który może przeglądać DAG-i, ich stan i logi, ale nie może ich edytować ani uruchamiać. Public - użytkownik bez autoryzacji, który ma dostęp tylko do bardzo ograniczonych informacji (lub nie ma dostępu do żadnych).
Oczywiście możemy definiować własne role, co będzie omówione w kolejnych rozdziałach.
Po wykonaniu naszego polecenia zobaczymy na konsoli ogromną ilość informacji w temacie tworzenia ról użytkownika i przypisywania do nich odpowiednich uprawnień. Tak wiele zadań występuje za każdym razem, kiedy tworzymy użytkownika lub wykonujemy jakiekolwiek polecenie związane z uprawnieniami na świeżej bazie danych dla Apache Airflow. Jeżeli wszystko pójdzie dobrze, to na końcu pojawi się informacja, że użytkownik został utworzony (rysunek 0.4).
Rysunek 0.4. Potwierdzenie utworzenia użytkownika
Powoli zbliżamy się do końca - możemy nareszcie uruchomić Apache Airflow. Będzie się on składał z dwóch elementów: webserver oraz scheduler. Oba elementy będą działać w terminalu, dopóki nie zamkniemy okien. Aby uruchomić narzędzia, wykonujemy poniższe polecenia, każde w innym terminalu:
nohup airflow webserver
nohup airflow scheduler
Pozostaje nam jeszcze zweryfikować nasze pliki z logami. Jeżeli webserver i scheduler uruchomiły się prawidłowo, to w pliku znajdziemy wpisy podobne do tych na rysunkach 0.5 oraz 0.6. Dodatkowo pojawi się nowy plik: airflow-webserver.pid, zawierający ID procesu, na którym działa webserver.
Rysunek 0.5. Potwierdzenie uruchomienia webservera
Rysunek 0.6. Potwierdzenie uruchomienia schedulera
Możesz wykorzystać narzędzie nohup i znak & do uruchomienia zadań w tle. Przykładowe polecenia:
nohup airflow webserver > webserver_$(date +'%Y%m%d%H%M').log &
nohup airflow scheduler > scheduler_$(date +'%Y%m%d%H%M').log &
Powyższe wpisy oczywiście mogą się różnić od moich. Najważniejsze, aby w plikach pojawiła się informacja, że dla webservera uruchomiono serwer gunicorn, który działa pod adresem localhost na porcie 8080, oraz workery, które działają na porcie 8793.
Nareszcie jesteśmy gotowi, aby zalogować się do Apache Airflow. Przechodzimy na https://localhost:8080 w naszej przeglądarce i widzimy ekran powitalny (rysunek 0.7). Na środku mamy formularz pozwalający na zalogowanie się do orkiestratora, natomiast w prawym górnym rogu informacje o czasie oraz możliwość ustawienia strefy czasowej do wyświetlenia. Domyślnie będziemy mieli do wyboru czas UTC i naszą strefę czasową oraz czas ustawiony w airflow.cfg (obok strefy czasowej serwera zobaczymy niebieski prostokąt z napisem Server), a także przycisk przenoszący do formularza logowania.
Rysunek 0.7. Formularz logowania do Apache Airflow
Podajemy dane logowania naszego użytkownika (którego niedawno utworzyliśmy) i widzimy "ekran powitalny" Apache Airflow (rysunek 0.8). Nareszcie mamy gotowe środowisko pracy!
Rysunek 0.8. Ekran po zalogowaniu
Pokrótce omówię poszczególne elementy strony głównej - szersze opisy pojawią się w kolejnych rozdziałach. Na górnej belce (ten sam poziom co logo orkiestratora) mamy sekcje:
DAGs - ekran główny, na którym aktualnie się znajdujemy.
Cluster Activity - statystyka oraz podstawowy monitoring naszego klastra.
Datasets - lista i aktywność zbiorów danych oraz elementów, które z nich korzystają.
Security - kwestie administracyjne, jak tworzenie ról użytkownika czy samych użytkowników.
Browse - sekcja pozwalająca przeglądać historie wykonywania zadań bądź DAG-ów.
Admin - ma dostęp do dodatkowych elementów dla naszych zadań, np. do połączenia do baz danych, zmiennych globalnych.
Docs - odnośniki do oficjalnej dokumentacji Airflow. Przyciski umożliwiające ustawienie jasnego/ciemnego motywu, wyświetlenia czasu w wybranej strefie czasowej, nazwa naszego użytkownika.
Wróćmy teraz do głównej zakładki. Będziemy mieli tutaj wyświetloną listę naszych DAG-ów i ogólną statystykę (liczba zatrzymanych DAG-ów, wyszukiwarka po etykietach/nazwie i odświeżenie stanu listy). Dla każdego DAG-a będziemy widzieć informacje (od lewej):
Czy jest zatrzymany. Nazwa wraz z etykietami (
DAG). Właściciel (
Owner) - domyślnie
airflow. Historia uruchomień (
Runs) - są to wszystkie uruchomienia danego DAG-a. Harmonogram (
schedule). Ostatni czas wykonania (
Last Run). Kolejne planowane wykonanie (
Next Run). Aktualny stan zadań (
Recent Tasks) - jest to stan wszystkich aktualnie zaplanowanych zadań. Jeżeli DAG zostanie zatrzymany, to widzimy tylko ostatni status. Uruchomienie/przeładowanie/usunięcie DAG-a (
Actions). Odnośniki (
Links) - przejście do szczegółowego panelu wybranego DAG-a.
Na sam koniec możesz zajrzeć na profil użytkownika (rysunek 0.9). Będą tam informacje podane podczas jego tworzenia oraz opcja resetowania hasła i aktualizacji danych. Co ciekawe, nie mamy możliwości zmiany adresu e-mail.
Rysunek 0.9. Profil użytkownika