Parliamone
// tecnologie.workflow-orchestration

Workflow Orchestration

Esecuzione dichiarativa di grafi di dipendenze in sistemi distribuiti: paradigmi DAG-based e code-based, strategie di retry, e osservabilità delle pipeline.

Data EngineeringProcess Automation

Executive summary

Quando un sistema informativo complesso deve coordinare decine o centinaia di operazioni interdipendenti, trasformazioni di dati, addestramento di modelli, sincronizzazione tra servizi, garantire che ogni passaggio avvenga nell'ordine corretto, gestire i guasti senza intervento manuale e mantenere piena visibilità su ciò che accade diventa un problema concreto che rallenta le operazioni e aumenta il rischio di errori. Questo articolo analizza le principali piattaforme e i modelli per la coordinazione automatica di flussi di lavoro computazionali, esaminando come ciascun approccio risolva i problemi fondamentali di pianificazione, tolleranza ai guasti e tracciabilità. L'analisi evidenzia che il settore si è differenziato in due famiglie distinte, una centrata sulla descrizione statica delle dipendenze tra operazioni, l'altra sull'esecuzione duratura di codice applicativo, e che la scelta tra queste famiglie dipende dalla natura del problema più che dalla maturità dello strumento. Le sfide principali si sono spostate dalla semplice esecuzione in sequenza alla gestione intelligente delle risorse, al mantenimento aggiornato dei dati prodotti e alla capacità di ricostruire la storia completa di ogni elaborazione.


Background

L'orchestrazione di workflow computazionali nasce come risposta a un problema di coordinamento: in un sistema distribuito, l'esecuzione di task interdipendenti richiede un meccanismo centralizzato o distribuito che imponga l'ordine topologico delle dipendenze, gestisca i fallimenti e fornisca visibilità sullo stato di avanzamento. Il problema è formalmente riconducibile allo scheduling di Directed Acyclic Graph (DAG), studiato dalla comunità scientifica nel contesto del calcolo parallelo e distribuito fin dagli anni Novanta. Topcuoglu et al. [1] hanno proposto l'algoritmo HEFT (Heterogeneous Earliest Finish Time), una euristica list-based che calcola la priorità di ogni task in funzione del costo computazionale e del costo di comunicazione lungo il cammino critico, assegnando ciascun task alla risorsa che ne minimizza il tempo di completamento. HEFT rimane, a distanza di oltre vent'anni, uno dei riferimenti principali per lo scheduling di workflow scientifici su risorse eterogenee.

La letteratura successiva ha esteso il problema in molteplici direzioni. Shi e Dongarra [2] hanno condotto una survey sistematica degli algoritmi di scheduling per workflow scientifici moderni, classificandoli in euristiche statiche, meta-euristiche, e approcci runtime che includono strategie di retry, resubmission e recovery automatico. La survey identifica una tensione fondamentale tra ottimalità dello scheduling, un problema NP-hard nella formulazione generale, e praticabilità in ambienti cloud dove le risorse sono elastiche, eterogenee e soggette a failure transienti. Rodriguez e Buyya [3] hanno affrontato specificamente lo scheduling di workflow in ambienti cloud con vincoli di deadline, proponendo un algoritmo basato su particle swarm optimization che bilancia costo economico e rispetto dei vincoli temporali.

Nel contesto industriale, l'orchestrazione ha assunto una forma diversa da quella accademica. Mentre la ricerca si concentra sull'ottimizzazione dello scheduling su cluster HPC, l'industria ha prodotto piattaforme di orchestrazione generaliste progettate per data pipeline, processi ETL e workflow di machine learning. Apache Airflow, rilasciato come progetto open-source da Airbnb nel 2015, ha introdotto il paradigma "workflow as code": i DAG sono definiti come programmi Python, il che consente composizione programmatica, versionamento tramite Git e testing con strumenti standard [4]. Questa scelta architetturale ha definito un'intera generazione di orchestratori. Tuttavia, il modello DAG-based presenta limitazioni strutturali per workflow che richiedono interazioni dinamiche, branching condizionale complesso o esecuzioni di lunga durata con stato persistente, limitazioni che hanno motivato l'emergere di paradigmi alternativi.


Paradigmi di orchestrazione: DAG-based vs. code-based

La distinzione architetturale più significativa nell'ecosistema degli orchestratori contemporanei non riguarda le funzionalità superficiali, interfacce grafiche, integrazioni, supporto cloud, ma il modello computazionale sottostante. Si identificano due paradigmi fondamentali: l'orchestrazione DAG-based, in cui il workflow è descritto come un grafo statico di task e dipendenze, e l'orchestrazione code-based (o durable execution), in cui il workflow è un programma imperativo la cui esecuzione è resa duratura e fault-tolerant dal runtime.

Orchestrazione DAG-based

Nel paradigma DAG-based, il workflow è un grafo diretto aciclico in cui i nodi rappresentano unità di lavoro (task) e gli archi rappresentano dipendenze. Lo scheduler attraversa il grafo in ordine topologico, eseguendo ogni task solo quando tutte le sue dipendenze sono soddisfatte. Apache Airflow [4], Prefect [5] e Dagster [6] adottano questo paradigma, sebbene con differenze architetturali sostanziali nella semantica del grafo.

Il modello DAG-based presenta vantaggi strutturali: il grafo è ispezionabile staticamente prima dell'esecuzione, il che consente visualizzazione, validazione delle dipendenze e ottimizzazione dello scheduling. La separazione tra definizione del workflow e runtime di esecuzione permette di ragionare sul workflow come artefatto dichiarativo. Tuttavia, il grafo deve essere completamente risolvibile prima dell'esecuzione: le dipendenze dinamiche, dove il numero di task o la struttura del grafo dipende dal risultato di un task precedente, richiedono meccanismi aggiuntivi (dynamic task mapping in Airflow, dynamic graphs in Prefect) che estendono il modello ma ne complicano la semantica.

Durable execution

Il paradigma alternativo, esemplificato da Temporal [7], ribalta la prospettiva: il workflow è un programma scritto in un linguaggio general-purpose (Go, Java, Python, TypeScript) la cui esecuzione è resa duratura dal runtime attraverso event sourcing e replay deterministico. Il Temporal Service registra ogni decisione del workflow come evento in una history durabile; in caso di failure, il runtime ri-esegue il codice del workflow dall'inizio, ma le chiamate a servizi esterni (activities) non vengono ripetute, il runtime sostituisce ciascuna con il risultato registrato nella event history [7]. Questo meccanismo consente workflow di durata arbitraria (giorni, mesi, anni) con garanzie di exactly-once semantics sulle side effects.

Il vincolo fondamentale della durable execution è il determinismo: il codice del workflow deve produrre la stessa sequenza di comandi data la stessa sequenza di eventi. Operazioni non deterministiche, generazione di numeri casuali, accesso all'orologio di sistema, I/O diretto, devono essere incapsulate in activities o nelle API deterministiche fornite dal runtime [7]. Questa restrizione, apparentemente limitante, ha una motivazione formale rigorosa: durante il replay, il runtime verifica che la sequenza di comandi generata dal codice corrisponda alla sequenza registrata nella event history. Un mismatch indica una violazione del determinismo e produce un non-determinism error che blocca l'esecuzione, un meccanismo di sicurezza che previene corruzioni silenziose dello stato del workflow.

Trade-off tra i due paradigmi

La scelta tra DAG-based e durable execution non è una questione di superiorità tecnologica, ma di adeguatezza al dominio del problema. Il paradigma DAG-based è ottimale per pipeline di dati con struttura nota a priori, ETL, feature engineering, addestramento batch, dove la visualizzazione del grafo e l'ispezionabilità statica sono proprietà critiche. La durable execution è preferibile per workflow applicativi con interazioni complesse, orchestrazione di microservizi, processi di approvazione multi-step, saga pattern per transazioni distribuite, dove il flusso di controllo è intrinsecamente imperativo e la durata dell'esecuzione è indeterminata.


Architetture a confronto: Airflow, Dagster, Prefect, Temporal

Apache Airflow: l'orchestratore DAG-based di riferimento

Apache Airflow è il sistema di orchestrazione più adottato nell'ecosistema dei dati, con oltre 320 milioni di download nel 2024 [8]. L'architettura si compone di uno scheduler che monitora i DAG e triggera i task, un executor che gestisce l'esecuzione effettiva, un DAG processor che serializza le definizioni dei DAG nel metadata database, e un web server per l'interfaccia utente [4]. Lo scheduling loop opera in tre fasi: verifica quali DAG necessitano di una nuova DAG run, esamina un batch di DAG run per identificare task schedulabili, e accoda i task rispettando i limiti di concorrenza dei pool [4].

Airflow 3.0, rilasciato nell'aprile 2025, rappresenta il cambiamento architetturale più significativo nella storia del progetto [9]. La Task Execution Interface (AIP-72) introduce un'architettura client-server che disaccoppia l'esecuzione dei task dallo scheduler: i task comunicano con il sistema tramite una REST API, non tramite accesso diretto al metadata database. Questa separazione consente l'esecuzione di task in ambienti remoti, container, edge computing, runtime eterogenei, attraverso il Task SDK, un runtime leggero che pone le basi per l'esecuzione language-agnostic [9]. L'Edge Executor (AIP-69) estende questa architettura a scenari di edge computing distribuito. Il DAG versioning consente l'ispezione delle definizioni storiche dei DAG, e le backfill gestite dallo scheduler sostituiscono il meccanismo precedente basato su CLI [9].

L'architettura di Airflow 3.0 converge verso un modello in cui tutte le interazioni tra componenti transitano attraverso un API Server, riducendo il carico sul database, eliminando la contesa di lock e migliorando la scalabilità orizzontale. L'interfaccia utente è stata completamente riscritta in React e FastAPI, sostituendo il frontend Flask precedente [9].

Dagster: orchestrazione asset-based

Dagster [6] introduce un cambio di paradigma rispetto all'orchestrazione task-based: l'unità fondamentale non è il task da eseguire, ma l'asset da produrre. Un software-defined asset (SDA) è una dichiarazione in codice di quale artefatto di dati deve esistere e come deve essere calcolato [10]. Le dipendenze tra asset sono definite implicitamente dai parametri della funzione decorata con @asset, e il grafo delle dipendenze emerge dalla composizione delle dichiarazioni, non da una definizione esplicita del DAG.

Questa inversione, dall'imperativo "esegui questi task in questo ordine" al dichiarativo "questi asset devono esistere con queste proprietà", ha implicazioni architetturali profonde. Il sistema di reconciliation di Dagster confronta lo stato desiderato degli asset con lo stato attuale e materializza solo gli asset che risultano stale o missing [10]. Una freshness policy dichiara quando un asset è considerato obsoleto, ad esempio, quando un asset upstream ha una materializzazione più recente, e il daemon di auto-materializzazione schedula le esecuzioni necessarie per riportare il sistema allo stato desiderato [11]. Rispetto allo scheduling basato su cron, dove le pipeline vengono eseguite a intervalli fissi indipendentemente dal fatto che i dati siano cambiati, la reconciliation dichiarativa evita computazioni ridondanti e garantisce che i dati downstream riflettano le modifiche upstream.

Il sistema di partizioni di Dagster consente la materializzazione indipendente di sottoinsiemi di un asset, per data, regione geografica, o qualsiasi dimensione definita dall'utente, con tracking granulare dello stato di ciascuna partizione. L'observability integrata fornisce lineage a livello di asset con metadati strutturati (schema, row count, quality check) allegati a ciascuna materializzazione [6].

Prefect: orchestrazione event-driven con semantica transazionale

Prefect [5] si posiziona come alternativa a bassa frizione rispetto ad Airflow, con un'enfasi sulla semplicità di adozione: qualsiasi funzione Python può essere trasformata in un task orchestrato aggiungendo un decoratore, senza modifiche alla struttura del codice. Prefect 3.0, rilasciato in general availability nel settembre 2024, ha introdotto tre innovazioni architetturali significative [12].

La prima è la semantica transazionale: ogni task viene eseguito all'interno di una transazione che governa la persistenza del risultato. I task possono essere raggruppati in unità atomiche con hook on_commit e on_rollback che consentono la compensazione automatica delle side effect in caso di fallimento [12]. Questo modello, ispirato alla semantica delle transazioni nei database, rende i workflow intrinsecamente idempotenti: la riesecuzione di un task in un contesto identico non produce duplicazioni, perché il sistema carica il risultato precedente dalla transazione completata.

La seconda innovazione è il sistema di eventi e automazioni, precedentemente disponibile solo nella versione cloud. Gli eventi rappresentano osservazioni di cambiamenti di stato, il completamento di un flow, l'arrivo di un file in un bucket, il superamento di una soglia, e le automazioni definiscono azioni reattive a pattern di eventi [12]. Questo consente workflow event-driven senza polling, un modello più efficiente per pipeline che reagiscono a stimoli esterni.

La terza è l'architettura di esecuzione distribuita nativa, con supporto per l'esecuzione di task su piattaforme di calcolo parallelo come Ray e Dask, estendendo la capacità del sistema di eseguire workload computazionalmente intensivi senza gestione manuale dell'infrastruttura [5].

Il trade-off principale di Prefect riguarda la maturità dell'ecosistema e la stabilità delle API. La transizione da Prefect 1.x (basato su un modello di DAG esplicito con un server di orchestrazione centralizzato) a Prefect 2.x (decoratori, nessun DAG esplicito) e poi a Prefect 3.0 (transazioni, eventi) ha comportato riscritture significative che hanno imposto costi di migrazione alla base utenti. L'architettura client-side, dove l'orchestrazione avviene nel processo del client anziché nel server, semplifica il deployment ma limita la capacità del server di coordinare esecuzioni complesse in scenari multi-tenant.

Temporal: durable execution per workflow applicativi

Temporal [7] opera in un dominio architetturale diverso rispetto agli orchestratori di data pipeline. Il sistema è progettato per workflow applicativi di lunga durata, orchestrazione di microservizi, saga per transazioni distribuite, processi di business multi-step, dove il flusso di controllo è intrinsecamente imperativo e le interazioni con servizi esterni sono il cuore del workflow, non un effetto collaterale.

L'architettura di Temporal si fonda su tre componenti: il Temporal Service (cluster), che mantiene la event history e gestisce il dispatching dei task; i Worker, processi applicativi che eseguono il codice dei workflow e delle activities; e le Task Queue, code che disaccoppiano il Service dai Worker [7]. Un workflow è una funzione deterministica che può invocare activities (operazioni con side effect), avviare child workflow, impostare timer, e attendere signal esterni. Ogni invocazione di activity è registrata come evento nella history; in caso di failure del Worker, un altro Worker può riprendere l'esecuzione tramite replay della history, senza perdita di stato.

Le garanzie di Temporal sono più forti di quelle degli orchestratori DAG-based: un workflow, una volta avviato, procederà fino al completamento (o all'esplicita cancellazione) indipendentemente da crash dei Worker, restart del cluster o partizioni di rete. Le activities possono essere configurate con retry policy granulari, numero massimo di tentativi, intervallo iniziale, coefficiente di backoff, timeout di scheduling e di esecuzione, e supportano heartbeat per attività di lunga durata [7]. La combinazione di durable execution e retry configurabili rende Temporal particolarmente adatto all'implementazione del saga pattern, dove una sequenza di operazioni distribuite deve essere compensata in ordine inverso in caso di fallimento di un passaggio intermedio.


Scheduling e gestione delle risorse

Lo scheduling nei sistemi di workflow orchestration opera a un livello di astrazione diverso rispetto allo scheduling accademico su cluster HPC. Mentre HEFT [1] e le sue varianti ottimizzano il makespan globale su risorse eterogenee con costi di comunicazione noti, gli orchestratori industriali affrontano un problema più vincolato: rispettare le dipendenze del DAG distribuendo i task su un pool di worker con vincoli di concorrenza, priorità e risorse.

In Apache Airflow, lo scheduling è governato dal pool mechanism: ogni task è associato a un pool con un numero massimo di slot, e lo scheduler accoda i task rispettando simultaneamente i limiti del pool, la concorrenza per DAG e la concorrenza globale [4]. L'executor determina come i task vengono effettivamente eseguiti: il LocalExecutor li esegue come processi locali, il CeleryExecutor li distribuisce su worker Celery, il KubernetesExecutor crea un pod Kubernetes per ogni task. La scelta dell'executor ha implicazioni architetturali significative: il KubernetesExecutor offre isolamento completo e scaling elastico, ma introduce una latenza di startup per pod (tipicamente 5-15 secondi) che lo rende inadatto per workflow con molti task di breve durata.

Dagster implementa uno scheduling dichiarativo che supera il paradigma cron-based [11]. Invece di definire "esegui questa pipeline ogni ora", l'operatore dichiara "questo asset deve essere aggiornato entro 30 minuti dalla materializzazione del suo upstream". Il daemon di auto-materializzazione calcola il piano di esecuzione necessario per soddisfare le freshness policy di tutti gli asset, tenendo conto delle dipendenze transitive e dello stato corrente di ciascun asset. Questo approccio elimina il problema delle pipeline ridondanti, un difetto strutturale dello scheduling cron-based in cui pipeline diverse ricalcolano dati già disponibili, e introduce una forma di ottimizzazione globale dello scheduling basata sullo stato osservato del sistema.

Temporal gestisce lo scheduling con un modello pull-based: i Worker sottoscrivono task queue e prelevano work item quando hanno capacità disponibile [7]. Questo modello è intrinsecamente auto-bilanciante, i Worker lenti ricevono meno task, e supporta priorità tramite task queue separate. La scalabilità orizzontale si ottiene aggiungendo Worker alla stessa task queue; il Temporal Service gestisce il deduplication e il dispatching.


Strategie di retry e tolleranza ai guasti

La gestione dei fallimenti è il problema architetturale che più differenzia un orchestratore da un semplice scheduler. In un sistema distribuito, i fallimenti sono la norma: errori di rete transienti, timeout di servizi downstream, esaurimento di risorse, e bug applicativi producono failure con caratteristiche diverse che richiedono strategie di recovery diverse.

Classificazione dei fallimenti

La progettazione di una strategia di retry efficace richiede innanzitutto una tassonomia dei fallimenti, perché strategie diverse sono appropriate per categorie diverse. I fallimenti transienti, timeout di rete, rate limiting, indisponibilità temporanea di un servizio, sono recuperabili tramite retry automatico senza intervento umano e costituiscono la maggioranza dei fallimenti in sistemi distribuiti ben progettati. I fallimenti deterministici, errori di logica, dati malformati, violazioni di schema, non beneficiano del retry perché producono lo stesso errore ad ogni tentativo; la strategia corretta è l'interruzione immediata con notifica, evitando di consumare risorse in tentativi inutili. I fallimenti di infrastruttura, crash del worker, esaurimento di memoria, failure del nodo, richiedono rischedulazione su risorse alternative e rappresentano il caso in cui la distinzione tra orchestratore e semplice scheduler diventa critica: un orchestratore maturo deve rilevare il tipo di fallimento e applicare la strategia appropriata, non un retry generico.

Exponential backoff con jitter

La strategia di retry più diffusa nei sistemi distribuiti è l'exponential backoff con jitter, formalizzata nelle best practice di AWS [13]. L'intervallo tra tentativi successivi cresce esponenzialmente, $t_n = t_0 \cdot b^n$ dove $t_0$ è l'intervallo iniziale, $b$ il fattore di backoff e $n$ il numero del tentativo, evitando di sovraccaricare il servizio in failure. L'aggiunta di jitter, una componente casuale che perturba l'intervallo calcolato, previene il fenomeno del retry storm, in cui multipli client sincronizzano i tentativi producendo picchi di carico periodici che perpetuano il fallimento. La variante "full jitter" ($t_n = \text{random}(0, t_0 \cdot b^n)$) produce la distribuzione di carico più uniforme [13].

Idempotenza come prerequisito

L'efficacia delle strategie di retry presuppone l'idempotenza delle operazioni: eseguire la stessa operazione multiple volte deve produrre lo stesso effetto di un'esecuzione singola [13]. Per operazioni di lettura, l'idempotenza è intrinseca. Per operazioni di scrittura, inserimento di record, invio di notifiche, esecuzione di pagamenti, l'idempotenza deve essere garantita esplicitamente, tipicamente tramite chiavi di idempotenza (idempotency key) che consentono al servizio ricevente di deduplicare richieste ripetute. I sistemi di orchestrazione moderni integrano il supporto all'idempotenza a livello di framework: Prefect 3.0 lo implementa tramite la semantica transazionale con result caching [12]; Temporal lo garantisce strutturalmente tramite il replay deterministico, dove le activities completate non vengono ri-eseguite [7].

Implementazioni a confronto

Airflow implementa il retry a livello di task con parametri configurabili: retries (numero massimo di tentativi), retry_delay (intervallo tra tentativi), e retry_exponential_backoff (flag per abilitare il backoff esponenziale) [4]. Il meccanismo opera a granularità di task instance: un task fallito viene rischedulato con il delay configurato, e il numero di tentativi è tracciato nel metadata database. Questo approccio è sufficiente per fallimenti transienti in pipeline batch, ma non fornisce meccanismi nativi per la compensazione di side effect parziali.

Temporal offre il modello di retry più granulare: ogni activity può essere configurata con una retry policy che specifica initial interval, backoff coefficient, maximum interval, maximum attempts e non-retryable error types [7]. Il sistema distingue tra activity timeout (il tempo massimo per un singolo tentativo), schedule-to-close timeout (il tempo massimo complessivo inclusi tutti i retry), e heartbeat timeout (il tempo massimo senza heartbeat prima che l'activity sia considerata fallita). L'heartbeat mechanism consente alle activities di lunga durata di segnalare il proprio progresso: in caso di failure e retry, l'activity può riprendere dall'ultimo heartbeat anziché ricominciare dall'inizio.

Dagster implementa una policy di retry a livello di op (l'unità di computazione all'interno di un asset) con supporto per retry count e delay [6]. La vera innovazione è nel modello di reconciliation: quando una materializzazione di un asset fallisce, il sistema mantiene traccia dello stato parziale e può rimaterializzare selettivamente solo gli asset falliti e i loro downstream, senza rieseguire l'intero grafo.


Osservabilità delle pipeline

L'osservabilità di un sistema di workflow orchestration opera su tre livelli distinti: lo stato di esecuzione dei workflow e dei task, la lineage dei dati prodotti e consumati, e le metriche di performance dell'infrastruttura sottostante. La convergenza di questi tre livelli in un framework unificato è una delle sfide architetturali aperte del settore.

Stato di esecuzione e metadata

Ogni orchestratore mantiene un metadata store che traccia lo stato di ciascun workflow run e task run: pending, running, success, failed, retrying, skipped. Airflow persiste queste informazioni nel metadata database (PostgreSQL o MySQL) con granularità di task instance, inclusi log di esecuzione, durata, numero di retry e XCom (cross-communication data tra task) [4]. Dagster arricchisce il metadata con informazioni strutturate a livello di asset: schema, row count, quality check, e metadati custom definiti dall'utente, allegati a ciascuna materializzazione [6]. Questa granularità consente query come "quale versione del modello ML è stata addestrata su quale versione del dataset di training, con quali metriche di qualità?", una capacità critica per la riproducibilità e l'audit.

Data lineage con OpenLineage

OpenLineage [14] ha introdotto uno standard aperto per la raccolta di metadati di lineage attraverso sistemi eterogenei. La specifica definisce un modello di eventi (run start, run complete, run fail) con metadati strutturati su input, output e trasformazioni. A partire da Airflow 2.7, OpenLineage è integrato nativamente nel framework [14]; Dagster, Apache Spark, dbt e Flink supportano l'emissione di eventi OpenLineage tramite integrazioni dedicate. Marquez [15], l'implementazione di riferimento, aggrega gli eventi in un grafo di lineage navigabile che consente l'analisi di impatto (quali dataset sono affetti da un cambiamento upstream) e la root cause analysis (quale job ha prodotto un dato errato).

La lineage cross-platform è il valore architetturale distintivo di OpenLineage rispetto alla lineage nativa di ciascun orchestratore: in un ecosistema dove i dati transitano da Airflow a Spark a dbt, la lineage end-to-end richiede un protocollo comune che attraversi i confini dei singoli sistemi [14].

Distributed tracing con OpenTelemetry

OpenTelemetry (OTel) [16] è lo standard CNCF per la raccolta di tracce, metriche e log in sistemi distribuiti, e il secondo progetto più attivo della CNCF dopo Kubernetes. Nel contesto della workflow orchestration, OTel consente di tracciare l'esecuzione di un workflow attraverso i servizi distribuiti che partecipano all'esecuzione: dallo scheduler che triggera il task, al worker che lo esegue, ai servizi esterni invocati dal task.

L'integrazione di OTel con gli orchestratori è in fase di maturazione. Temporal supporta nativamente l'emissione di span OpenTelemetry per workflow e activities, consentendo la correlazione tra l'esecuzione del workflow e le tracce dei servizi invocati [7]. Airflow ha introdotto il supporto OTel a partire dalla versione 2.7 con un provider dedicato. L'adozione di OTel per le pipeline di dati è tuttavia meno matura rispetto all'adozione nei microservizi, in parte perché il modello di tracing, ottimizzato per request-response con latenza in millisecondi, si adatta meno naturalmente a pipeline batch con esecuzioni di minuti o ore.

La convergenza tra lineage (OpenLineage) e tracing (OpenTelemetry) è un'area di sviluppo attivo: i due standard catturano aspetti complementari dell'esecuzione, la lineage descrive cosa è stato prodotto da cosa, il tracing descrive come e quando è stato eseguito, e la loro integrazione fornirebbe una vista unificata che oggi richiede la correlazione manuale di sistemi separati.


Limiti e problemi aperti

Complessità operativa

Tutti gli orchestratori esaminati introducono complessità infrastrutturale significativa. Airflow richiede la gestione di scheduler, webserver, database, e worker; Temporal richiede il cluster Temporal Service con i suoi requisiti di persistenza (Cassandra, MySQL o PostgreSQL) e di visibilità (Elasticsearch); Dagster richiede daemon, webserver e user code deployment separati. Le versioni managed (Astronomer per Airflow, Temporal Cloud, Dagster Cloud, Prefect Cloud) riducono questa complessità ma introducono dipendenza da vendor e costi operativi proporzionali all'utilizzo.

Testabilità

La testabilità dei workflow rimane una sfida architetturale sottovalutata. Dagster ha posto la testabilità come principio di design fin dall'origine, con risorse iniettabili e un framework di testing che consente l'esecuzione di asset individuali con dipendenze mock [6]. Airflow ha storicamente offerto supporto limitato al testing unitario dei DAG, sebbene Airflow 3.0 migliori la situazione con la separazione tra definizione del DAG e runtime. Temporal consente il testing dei workflow tramite un ambiente di replay che simula l'esecuzione senza invocare servizi reali [7]. In generale, il testing end-to-end di workflow complessi, che coinvolgono servizi esterni, database e sistemi distribuiti, rimane un problema largamente irrisolto nella pratica industriale.

Interoperabilità

L'assenza di uno standard di interoperabilità tra orchestratori è un limite strutturale dell'ecosistema. Un workflow definito in Airflow non è portabile su Dagster o Prefect senza riscrittura. OpenLineage [14] affronta parzialmente il problema a livello di metadati, ma non esiste un equivalente per la definizione dei workflow stessi. Lo standard CNCF Serverless Workflow Specification ha proposto un formato dichiarativo basato su JSON/YAML, ma l'adozione rimane limitata rispetto ai DSL nativi di ciascun orchestratore.

Scalabilità del grafo

Per workflow con migliaia di task, comuni nelle pipeline di dati di grandi organizzazioni, la serializzazione, il parsing e la visualizzazione del DAG diventano colli di bottiglia. Airflow 3.0 ha mitigato il problema con la serializzazione nel database e il DAG processor separato [9], ma il costo di scheduling cresce linearmente con il numero di task. Le architetture che disaccoppiano la pianificazione dall'esecuzione, come il modello Temporal, dove il cluster gestisce lo stato e i Worker gestiscono l'esecuzione, scalano più naturalmente, ma al costo di una maggiore complessità infrastrutturale.

Convergenza e frammentazione dell'ecosistema

L'ecosistema della workflow orchestration è in fase di frammentazione attiva: oltre ai quattro sistemi analizzati in profondità, piattaforme come Kestra (orchestrazione dichiarativa basata su YAML con supporto multi-linguaggio) e Restate (durable execution con modello a funzioni virtuali) occupano nicchie architetturali specifiche. Questa proliferazione riflette la mancanza di un modello computazionale unificante che copra simultaneamente pipeline di dati batch, workflow applicativi long-running e orchestrazione event-driven. La tendenza alla convergenza funzionale, Airflow che aggiunge supporto event-driven, Temporal che estende il supporto a pipeline di dati, rischia di produrre sistemi che fanno tutto in modo mediocre piuttosto che eccellere nel proprio dominio nativo.


Implicazioni architetturali per il deployment in produzione

La scelta dell'orchestratore in un contesto di produzione dipende da quattro fattori principali: la natura del workflow (batch vs. long-running), la granularità del retry richiesta, i requisiti di osservabilità e la maturità dell'ecosistema.

Per pipeline di dati batch, ETL, feature engineering, addestramento periodico di modelli, Airflow e Dagster rappresentano le scelte consolidate. Airflow offre il più ampio ecosistema di operator e integrazioni, con una community di dimensioni significative e una base di conoscenza estesa; Dagster offre un modello concettuale più rigoroso con il paradigma asset-based, testabilità superiore e reconciliation dichiarativa, al costo di un ecosistema più giovane. Prefect si colloca come alternativa a frizione minima per team che privilegiano la velocità di adozione e la flessibilità dell'architettura event-driven.

Per workflow applicativi, orchestrazione di microservizi, saga distribuite, processi di approvazione, Temporal è architetturalmente superiore: le garanzie di durable execution, la granularità del retry, e il supporto per workflow di durata arbitraria rispondono a requisiti che i sistemi DAG-based non possono soddisfare senza workaround significativi. Il costo è una curva di apprendimento più ripida e la necessità di rispettare i vincoli di determinismo nel codice del workflow.

In architetture complesse, la coesistenza di più orchestratori è un pattern emergente: Temporal per l'orchestrazione dei servizi applicativi, Airflow o Dagster per le pipeline di dati, con OpenLineage come strato di metadata unificante e OpenTelemetry per il tracing cross-system. Questa architettura poliglotta riflette il principio che strumenti diversi sono ottimali per domini diversi, un principio che la convergenza funzionale dei singoli orchestratori non ha ancora invalidato.


Riferimenti

[1] H. Topcuoglu, S. Hariri, M. Wu, "Performance-Effective and Low-Complexity Task Scheduling for Heterogeneous Computing," in IEEE Transactions on Parallel and Distributed Systems, vol. 13, no. 3, 2002. https://doi.org/10.1109/71.993206

[2] Y. Shi, J. Dongarra, "A Survey of Modern Scientific Workflow Scheduling Algorithms and Systems," Wayne State University, 2020. https://shiyong.eng.wayne.edu/papers/survey2020.pdf

[3] M. A. Rodriguez, R. Buyya, "Deadline Based Resource Provisioning and Scheduling Algorithm for Scientific Workflows on Clouds," in IEEE Transactions on Cloud Computing, vol. 2, no. 2, 2014. https://doi.org/10.1109/TCC.2014.2314655

[4] Apache Software Foundation, "Apache Airflow Documentation," 2025. https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/overview.html

[5] Prefect Technologies, "Prefect Documentation," 2025. https://docs.prefect.io/

[6] Dagster Labs, "Dagster Documentation," 2025. https://docs.dagster.io/

[7] Temporal Technologies, "Temporal Platform Documentation," 2025. https://docs.temporal.io/workflows

[8] PracData, "State of Open Source Workflow Orchestration Systems 2025," 2025. https://www.pracdata.io/p/state-of-workflow-orchestration-ecosystem-2025

[9] Apache Software Foundation, "Apache Airflow 3 is Generally Available," 2025. https://airflow.apache.org/blog/airflow-three-point-oh-is-here/

[10] Dagster Labs, "What Are Software-Defined Assets?," 2023. https://dagster.io/blog/software-defined-assets

[11] Dagster Labs, "Dagster 1.1: Declarative Scheduling," 2023. https://dagster.io/blog/dagster-1-1-thank-u-next

[12] Prefect Technologies, "Introducing Prefect 3.0," 2024. https://www.prefect.io/blog/introducing-prefect-3-0

[13] Amazon Web Services, "Timeouts, Retries and Backoff with Jitter," AWS Builders' Library, 2019. https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/

[14] OpenLineage Project, "OpenLineage Documentation," 2025. https://openlineage.io/

[15] Marquez Project, "Marquez: Open Source Metadata Service for the Data Ecosystem," 2025. https://marquezproject.ai/

[16] OpenTelemetry Authors, "OpenTelemetry Documentation," CNCF, 2025. https://opentelemetry.io/docs/concepts/observability-primer/

Workflow Orchestration

Raccontaci la situazione. Rispondiamo entro 24 ore nei giorni lavorativi.

Tweaks

Light mode
Atmospheric (glass)
Client logos
Terminal hero