Torna al blog
Orchestrazione di Pipeline: Airflow, Prefect e Dagster a Confronto

Orchestrazione di Pipeline: Airflow, Prefect e Dagster a Confronto

7 min di lettura1 visualizzazioni
di Marco Salmaso
Airflow, Prefect e Dagster fanno la stessa cosa in modi molto diversi. Guida pratica per scegliere l'orchestratore giusto in base a team, numero di pipeline e bisogno di lineage, evitando di partire dal tool sbagliato.

Quando una pipeline di dati vive in un solo script Python, lanciato a mano quando serve, non c'è niente di sbagliato. Il problema arriva dopo: quando le pipeline diventano tre, poi cinque, dipendono l'una dall'altra, devono girare ogni notte e qualcuno deve accorgersi se una fallisce. A quel punto lo script non basta più e serve un orchestratore.

Questo articolo mette a confronto i tre strumenti che si incontrano più spesso in progetti reali: Airflow, Prefect e Dagster. Non è una classifica: sono strumenti diversi, nati in momenti diversi, e la scelta sbagliata si paga con mesi di attrito.

Cosa fa davvero un orchestratore

Prima di guardare gli strumenti conviene fissare le funzioni. Un orchestratore non trasforma i dati: quello lo fanno il codice e il database. L'orchestratore decide quando, in che ordine e cosa fare se qualcosa va storto.

Le funzioni minime sono cinque:

  • Scheduling: far partire un lavoro a un'ora prestabilita o a intervalli regolari.
  • Dipendenze: sapere che il caricamento non può partire prima dell'estrazione.
  • Retry: ritentare automaticamente un passo fallito, con un limite, invece di aspettare che un umano se ne accorga.
  • Osservabilità: log, stato di ogni esecuzione, notifiche quando qualcosa si rompe.
  • Backfill: rieseguire i giorni passati quando si corregge un bug o si cambia la logica.

Tutto il resto — dashboard, integrazioni, plugin — è contorno. Se un tool copre bene queste cinque cose, è già un orchestratore serio.

Airflow: il veterano

Airflow è nato in Airbnb nel 2014 ed è diventato lo standard de facto. La fortuna è anche la sua condanna: c'è un ecosistema enorme di operator, provider e documentazione, ma il modello mentale è rimasto quello degli inizi.

In Airflow si scrive un DAG (grafo aciclico diretto) in Python. I nodi sono task, e l'ordine si esprime con l'operatore di dipendenza.

from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime

def estrai():
    ...

def carica():
    ...

with DAG(
    dag_id="carica_vendite",
    start_date=datetime(2024, 1, 1),
    schedule="0 2 * * *",
    catchup=False,
) as dag:
    t1 = PythonOperator(task_id="estrai", python_callable=estrai)
    t2 = PythonOperator(task_id="carica", python_callable=carica)
    t1 >> t2

Il vantaggio è la maturità: chiunque abbia lavorato con dati ha visto un DAG di Airflow e sa orientarsi. Lo svantaggio è il peso. Anche un progetto piccolo richiede un database di metadati, uno scheduler, un webserver e almeno un worker. In locale si parte con Docker Compose, ma sono comunque cinque container. In più il paradigma è task-oriented: si descrive cosa eseguire, non quale dato produrre. Il lineage bisogna costruirlo a parte.

Airflow ha senso quando il team è grande, le pipeline sono centinaia e c'è già qualcuno che lo conosce. Partire da zero con Airflow per due DAG è come comprare un camion per andare a fare la spesa.

Prefect: Python prima di tutto

Prefect è nato con una critica esplicita ad Airflow: troppa infrastruttura per un problema che, spesso, è solo "queste funzioni devono girare in quest'ordine". La risposta è stata rendere l'orchestrazione trasparente: si scrivono funzioni Python normali e si decorano.

from prefect import flow, task

@task(retries=3, retry_delay_seconds=60)
def estrai():
    ...

@task
def carica(dati):
    ...

@flow
def pipeline():
    dati = estrai()
    carica(dati)

if __name__ == "__main__":
    pipeline()

Il codice si può eseguire anche come script normale: python pipeline.py funziona. Questo cambia molto il ciclo di sviluppo, perché si può debuggare senza avviare una piattaforma. Le dipendenze si esprimono passando valori tra le funzioni, non con un grafo esplicito: se carica riceve l'output di estrai, allora dipende da estrai. È un'idea semplice che elimina una buona parte del boilerplate.

Prefect in produzione si appoggia a un server (self-hosted o cloud) che tiene traccia delle esecuzioni. L'installazione è più leggera di Airflow, ma il progetto è più giovane e l'ecosistema di integrazioni è più piccolo. Se vi serve un operatore già pronto per un sistema esotico, è probabile che in Airflow esista e in Prefect no.

Dagster: gli asset al centro

Dagster ribalta il punto di partenza. Invece di chiedersi "quali task devo eseguire?", chiede "quali dati devo produrre?". L'unità di base è l'asset: una tabella, un file, un modello, qualcosa che ha un nome e uno stato.

from dagster import asset
import pandas as pd

@asset
def vendite_grezze() -> pd.DataFrame:
    return pd.read_csv("vendite.csv")

@asset
def vendite_pulite(vendite_grezze: pd.DataFrame) -> pd.DataFrame:
    return vendite_grezze.dropna()

Le dipendenze si esprimono nei parametri della funzione, come in Prefect, ma qui il sistema sa anche che vendite_pulite è un oggetto che esiste nel tempo. Questo permette cose che negli altri due strumenti richiedono lavoro extra:

  • Lineage automatico: si vede da dove arriva ogni tabella.
  • Materializzazione selettiva: si può ricostruire solo un asset e i suoi antenati.
  • Controlli di qualità dichiarati accanto all'asset, non in un sistema separato.

Il prezzo è un vocabolario più ricco da imparare. Dagster non è complicato, ma non è nemmeno "solo decoratori": ha concetti propri (asset, op, job, schedule, sensor, resource) e bisogna capirli prima di scrivere qualcosa di sensato.

Confronto rapido

CriterioAirflowPrefectDagster
Modello mentaleTaskFlowAsset
Curva inizialeAltaBassaMedia
Infrastruttura minimaPesanteLeggeraMedia
EcosistemaEnormeBuonoBuono
Lineage datiEsternoBaseNativo
Test in localeScomodoSempliceBuono
Adatto aTeam grandiTeam piccoli/mediProgetti data-centrici

La tabella è una semplificazione: tutti e tre gli strumenti possono fare le stesse cose, cambia quanto codice serve per farlo.

Come scegliere senza pentirsi

Alcune domande pratiche che funzionano meglio di qualsiasi benchmark.

Quante pipeline avete? Se sono una o due, un cron e uno script con logging possono bastare. Se sono più di dieci e hanno dipendenze incrociate, serve un orchestratore vero.

Chi ci lavora? Se il team è composto da data engineer esperti di Airflow, cambiare ha un costo. Se ci lavorano anche analisti che scrivono Python, Prefect o Dagster sono più accessibili.

Vi interessa il lineage? Se il problema è "non sappiamo da dove arriva questo numero", Dagster è costruito esattamente per rispondere a questa domanda.

Quanta infrastruttura potete mantenere? Un orchestratore è un sistema in produzione: ha bisogno di aggiornamenti, backup, monitoraggio. Meno pezzi, meglio è.

Un criterio poco scientifico ma utile: provate a riscrivere la pipeline più semplice che avete nei tre strumenti. Se una vi risulta innaturale, probabilmente lo resterà anche dopo mesi.

Un esempio concreto

Immaginiamo una pipeline notturna tipica di un piccolo e-commerce: estrarre gli ordini dal gestionale, pulirli, caricarli nel data warehouse, aggiornare una dashboard. Non è un caso reale, è solo un esempio per confrontare i modelli.

In Airflow si scrivono quattro task, si collegano con >>, si aggiunge uno schedule 0 3 * * * e un retries=2 sull'estrazione. Il DAG è chiaro ma verboso.

In Prefect si scrivono quattro funzioni decorate, si chiamano dentro un @flow, e si ottiene gratis retry e osservabilità. Il codice assomiglia a quello che avreste scritto comunque.

In Dagster si definiscono quattro asset: ordini_grezzi, ordini_puliti, ordini_warehouse, dashboard. Le dipendenze emergono dai parametri. In cambio si ha un grafo dei dati navigabile e la possibilità di ricostruire solo un pezzo.

Nessuna delle tre versioni è "giusta". Sono tre modi diversi di descrivere lo stesso lavoro.

Conclusione

  • Un orchestratore serve quando le pipeline sono più di poche, hanno dipendenze e devono girare da sole. Copre scheduling, dipendenze, retry, osservabilità e backfill.
  • Airflow è lo standard: maturo, con un ecosistema enorme, ma pesante e task-oriented. Ha senso in team grandi con pipeline numerose.
  • Prefect mette Python al centro: meno boilerplate, debugging semplice, ottimo per team piccoli e medi.
  • Dagster parte dagli asset: lineage nativo e controlli di qualità integrati, ideale quando il problema è capire i dati, non solo eseguire codice.
  • La scelta giusta dipende da dimensione del team, numero di pipeline, infrastruttura sostenibile e da quanto conta il lineage. Provare a riscrivere una pipeline reale nei candidati è il modo più onesto di decidere.

Foto di copertina di Taylor Vick su Unsplash.