Airflow est l'orchestrateur de référence en data engineering. Mais beaucoup de profils se limitent aux DAGs basiques. Voici les concepts avancés qu'on teste pour valider un Data Engineer en production.
Airflow n'est pas un framework de traitement — c'est un orchestrateur. Comprendre cette distinction est la première chose qu'on vérifie en entretien. Un Data Engineer qui passe des datasets via XCom ou qui met de la logique métier dans ses DAGs n'a pas encore le niveau Senior.
Quelle est la différence entre un opérateur, un sensor et un task décorateur TaskFlow ? Dans quel cas utilisez-vous chacun ?
Un DAG (Directed Acyclic Graph) est un graphe orienté sans cycle. Il définit l'ordre d'exécution des tâches, leurs dépendances, leur scheduling — mais pas leur contenu métier. Le DAG est l'orchestrateur, pas le processeur.
from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime
with DAG(
dag_id="mon_pipeline",
start_date=datetime(2025, 1, 1),
schedule_interval="@daily",
catchup=False,
max_active_runs=1,
) as dag:
extract = PythonOperator(
task_id="extraction",
python_callable=extraire_donnees,
)
transform = PythonOperator(
task_id="transformation",
python_callable=transformer_donnees,
)
extract >> transform # dépendance : transform attend extractBonne pratique : 1 tâche = 1 responsabilité. Un DAG qui fait extraction + transformation + chargement dans une seule tâche Python est un anti-pattern — il casse l'observabilité et le retry granulaire.
Quels sont les avantages de la TaskFlow API par rapport aux PythonOperators classiques ? Quelles sont ses limites ?
Introduite en Airflow 2.0, la TaskFlow API simplifie radicalement l'écriture des DAGs Python en supprimant le boilerplate XCom explicite.
from airflow.decorators import dag, task
from datetime import datetime
@dag(schedule_interval="@daily", start_date=datetime(2025, 1, 1), catchup=False)
def mon_pipeline_taskflow():
@task
def extraire() -> dict:
return {"lignes": 1500, "source": "postgres"}
@task
def transformer(data: dict) -> dict:
return {"lignes_traitees": data["lignes"], "source": data["source"]}
@task
def charger(data: dict):
print(f"Chargement de {data['lignes_traitees']} lignes depuis {data['source']}")
# Les dépendances sont inférées automatiquement
charger(transformer(extraire()))
mon_pipeline_taskflow()Airflow est-il un framework de traitement de données ? Pourquoi ne faut-il pas passer de datasets via XCom ?
XCom (cross-communication) permet aux tâches d'échanger des informations. C'est un mécanisme léger, pas un système de transfert de données.
# Push explicite dans un PythonOperator classique
def ma_tache(**context):
context['task_instance'].xcom_push(key='nb_lignes', value=1500)
# Pull explicite
def tache_suivante(**context):
nb = context['task_instance'].xcom_pull(task_ids='ma_tache', key='nb_lignes')
print(f"Reçu : {nb} lignes")
# Avec TaskFlow : implicite, via le return
@task
def ma_tache() -> int:
return 1500 # automatiquement pushé en XComRappel fondamental : Airflow est un orchestrateur, pas un framework de traitement. Le traitement se fait dans Spark, dbt, ou les services cloud. Airflow déclenche et surveille — il ne traite pas.
Qu'est-ce qu'une trigger rule et dans quel cas utilisez-vous none_failed_min_one_success ?
Par défaut, Airflow n'exécute une tâche que si toutes ses tâches amont ont réussi. Les trigger rules permettent de modifier ce comportement.
| Trigger rule | Condition d'exécution | Cas d'usage |
|---|---|---|
all_success | Toutes les tâches amont ont réussi (défaut) | Pipeline standard |
all_failed | Toutes les tâches amont ont échoué | Notification d'échec global |
all_done | Toutes les tâches amont sont terminées (succès ou échec) | Nettoyage systématique |
one_success | Au moins une tâche amont a réussi | Traitement dès qu'une source est disponible |
none_failed | Aucune tâche amont n'a échoué (succès ou skipped) | Tâche finale après branchement conditionnel |
none_failed_min_one_success | Aucun échec + au moins un succès | Agrégation après branchement avec succès partiel |
Quels sont les composants d'une architecture Airflow en production ? Quelle est la différence entre LocalExecutor et CeleryExecutor ?
Une installation Airflow en production comporte plusieurs composants distincts. Connaître l'architecture est indispensable pour déployer et déboguer.
En production : LocalExecutor convient jusqu'à ~50 DAGs. Au-delà, CeleryExecutor ou KubernetesExecutor. MWAA (AWS Managed Airflow) et Cloud Composer (GCP) gèrent l'infrastructure automatiquement.
Comment gérez-vous les credentials dans Airflow ? Pourquoi ne faut-il pas les coder en dur dans les DAGs ?
| Niveau | Maîtrise attendue | Signal GO | NO-GO |
|---|---|---|---|
| Junior | DAGs basiques, PythonOperator, scheduling, dépendances simples | Comprend qu'Airflow est un orchestrateur, sait créer un DAG avec catchup=False | Confond Airflow avec un framework de traitement, met de la logique métier dans le DAG |
| Confirmé | TaskFlow API, XCom, trigger rules, branchement, connexions | Utilise TaskFlow, sait quand ne pas utiliser XCom, explique les trigger rules | Ne connaît pas TaskFlow, passe des DataFrames via XCom |
| Senior | Architecture executor, Secrets Backend, SLAs, dynamic task mapping | Cite CeleryExecutor vs KubernetesExecutor, a configuré un Secrets Backend | Ne sait pas expliquer la différence entre les executors |
| Lead | Architecture cloud (MWAA/Composer), standards équipe, CI/CD DAGs | A migré vers MWAA ou Composer, a mis en place des tests automatisés sur les DAGs | Ne peut pas expliquer comment déployer Airflow en haute disponibilité |
Premier entretien gratuit. Rapport GO/NO-GO sous 48h.