# Apache Airflow em 2026: orquestração de pipelines, DAG e perguntas de entrevista > Dominar o Apache Airflow 3.2 com este tutorial prático: escrita de DAG com o Task SDK, padrões de orquestração de pipelines, partições de assets e perguntas reais de entrevista para vagas de data engineering em 2026. - Published: 2026-06-13 - Updated: 2026-06-17 - Author: SharpSkill - Tags: apache-airflow, data-engineering, data-pipeline, orchestration, dag, interview, python - Reading time: 11 min --- O Apache Airflow 3.2 representa a evolução mais significativa da plataforma de orquestração open source desde a reformulação arquitetural da versão 3.0. Com mais de 10 milhões de downloads mensais no [PyPI](https://pypi.org/project/apache-airflow/) e adoção em empresas que vão da Airbnb ao Spotify, o Airflow continua sendo a ferramenta dominante para construir, agendar e monitorar pipelines de dados. Este tutorial cobre a escrita de DAG com o novo Task SDK, os padrões de orquestração de pipelines e as perguntas de entrevista que aparecem em vagas de data engineering. > **Airflow 3.2 em resumo** > > O Airflow 3.2, lançado em abril de 2026, introduz as partições de assets para um agendamento data-aware granular, o suporte assíncrono nativo no PythonOperator e os deployments multiequipe. Todas as importações de DAG passam agora pelo namespace estável `airflow.sdk` introduzido no Airflow 3.0. ## Escrita de DAG com o Task SDK do Airflow O Airflow 3.0 introduziu o [Task SDK](https://airflow.apache.org/docs/task-sdk/stable/index.html), um pacote independente que desacopla as definições de DAG dos componentes internos do Airflow. O objetivo: escrever DAGs portáteis e estáveis entre versões, capazes de sobreviver às atualizações do Airflow sem alterações de código. Todos os objetos centrais — `DAG`, `dag`, `task`, `BaseOperator`, `Connection`, `Variable` — residem agora sob `airflow.sdk`. Os caminhos de importação legados (`airflow.decorators.task`, `airflow.models.dag.DAG`) ainda funcionam na 3.2, mas estão marcados como obsoletos e serão removidos em uma versão futura. ```python # etl_daily_revenue.py import pendulum from airflow.sdk import dag, task @dag( schedule="@daily", start_date=pendulum.datetime(2026, 1, 1, tz="UTC"), catchup=False, tags=["finance", "etl"], ) def etl_daily_revenue(): @task() def extract_transactions() -> list[dict]: # Pulls raw transactions from the payments API import requests response = requests.get("https://api.internal/payments/daily") return response.json()["transactions"] @task(multiple_outputs=True) def transform(transactions: list[dict]) -> dict: # Aggregates by currency and computes totals totals = {} for tx in transactions: currency = tx["currency"] totals[currency] = totals.get(currency, 0) + tx["amount"] return {"totals": totals, "count": len(transactions)} @task() def load(totals: dict, count: int): # Inserts aggregated row into the warehouse from warehouse import insert_revenue_summary insert_revenue_summary(totals=totals, transaction_count=count) raw = extract_transactions() result = transform(raw) load(result["totals"], result["count"]) etl_daily_revenue() ``` O decorador `@dag` substitui o gerenciador de contexto tradicional `with DAG(...)`. O decorador `@task` transforma funções Python simples em tarefas do Airflow, com a serialização XCom tratada automaticamente. Chamar `transform(raw)` declara uma dependência — o Airflow constrói as arestas do DAG a partir do grafo de chamadas de funções. ## Mapeamento dinâmico de tarefas para cargas variáveis DAGs estáticos falham quando o número de itens a processar muda entre execuções. O mapeamento dinâmico de tarefas, estável desde o Airflow 2.4 e refinado no ramo 3.x, resolve isso gerando as tarefas em tempo de execução via `.expand()`. ```python # etl_multi_region.py import pendulum from airflow.sdk import dag, task @dag( schedule="@hourly", start_date=pendulum.datetime(2026, 1, 1, tz="UTC"), catchup=False, tags=["regional", "etl"], ) def etl_multi_region(): @task() def get_regions() -> list[str]: # Returns the active regions from config return ["us-east-1", "eu-west-1", "ap-southeast-1"] @task() def process_region(region: str) -> dict: # Processes events for a single region from data_processor import aggregate_events return aggregate_events(region) @task() def merge_results(results: list[dict]): # Combines all regional outputs into a single report from reporter import publish_global_report publish_global_report(results) regions = get_regions() # .expand() creates one mapped task instance per region processed = process_region.expand(region=regions) merge_results(processed) etl_multi_region() ``` Em tempo de execução, o Airflow cria três instâncias paralelas de `process_region` — uma por região. Se uma quarta região aparecer amanhã, nenhuma alteração no código do DAG é necessária. A tarefa `merge_results` aguarda a conclusão de todas as instâncias mapeadas antes de executar. > **Limites das tarefas mapeadas** > > Por padrão, o Airflow limita as tarefas mapeadas a 1024 instâncias por mapeamento. Esse limite é alterado com `max_map_length` na configuração do DAG ao processar conjuntos de dados maiores. ## Partições de assets: agendamento data-aware no Airflow 3.2 Antes do Airflow 3.2, o agendamento data-aware operava no nível do asset: quando um DAG produtor atualizava um asset, todos os DAGs consumidores eram disparados independentemente de qual fatia de dados havia mudado. As [partições de assets](https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/assets.html) corrigem isso ao habilitar uma granularidade no nível da partição. Considere um cenário em que três DAGs upstream produzem estatísticas horárias de jogadores para diferentes ligas esportivas. Um DAG analítico downstream só deveria disparar quando as três ligas tiverem publicado dados para a mesma hora. ```python # downstream_analytics.py import pendulum from airflow.sdk import dag, task from airflow.timetables.assets import CronPartitionTimetable # Define partitioned assets with hourly granularity nba_stats = Asset("s3://datalake/nba/hourly/", partitions=CronPartitionTimetable("0 * * * *")) epl_stats = Asset("s3://datalake/epl/hourly/", partitions=CronPartitionTimetable("0 * * * *")) nfl_stats = Asset("s3://datalake/nfl/hourly/", partitions=CronPartitionTimetable("0 * * * *")) @dag( # Triggers only when all three assets have matching partition schedule=(nba_stats & epl_stats & nfl_stats), start_date=pendulum.datetime(2026, 1, 1, tz="UTC"), catchup=False, ) def unified_sports_analytics(): @task() def aggregate_all_leagues(**context): partition = context["partition"] # Process only the specific hourly slice across all leagues from analytics import build_cross_league_report build_cross_league_report(partition=partition) aggregate_all_leagues() unified_sports_analytics() ``` O agendamento particionado elimina as execuções de pipeline redundantes. O DAG downstream só dispara quando a partição exata de que precisa está disponível em todas as fontes upstream — nem antes, nem sobre dados parciais. ## Tarefas assíncronas nativas para cargas intensivas em E/S O Airflow 3.2 adiciona [suporte assíncrono nativo](https://airflow.apache.org/blog/airflow-3.2.0/) no PythonOperator. Antes, executar operações de E/S concorrentes (milhares de chamadas de API, downloads de arquivos em lote) exigia escrever operadores deferrable personalizados. Agora, basta passar diretamente uma função `async`. ```python # async_file_download.py import asyncio import aiohttp from airflow.sdk import dag, task import pendulum @dag( schedule="@daily", start_date=pendulum.datetime(2026, 1, 1, tz="UTC"), catchup=False, tags=["async", "download"], ) def async_file_download(): @task() async def download_files(): urls = [f"https://data.source/files/{i}.csv" for i in range(500)] async with aiohttp.ClientSession() as session: # Downloads 500 files concurrently instead of sequentially tasks = [fetch_and_save(session, url) for url in urls] results = await asyncio.gather(*tasks) return {"downloaded": len(results)} download_files() async def fetch_and_save(session: aiohttp.ClientSession, url: str): async with session.get(url) as resp: content = await resp.read() filename = url.split("/")[-1] with open(f"/data/downloads/{filename}", "wb") as f: f.write(content) return filename async_file_download() ``` A abordagem assíncrona baixa 500 arquivos em paralelo por meio de um único slot de worker, contra 500 chamadas HTTP sequenciais na versão síncrona. Para cargas limitadas por E/S, isso se traduz em ganhos de velocidade de uma ordem de magnitude sem provisionar workers adicionais. ## Arquitetura do Airflow: componentes e fluxo de execução Compreender a [arquitetura do Airflow](https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/overview.html) é essencial tanto para operá-lo em produção quanto para responder a perguntas de entrevista. Cinco componentes interagem durante cada execução de DAG: - **Scheduler** — Faz o parse dos arquivos de DAG, resolve as dependências e enfileira as tarefas para execução. No Airflow 3.x, o scheduler opera sem estado contra o banco de metadados. - **Executor** — Determina onde as tarefas são executadas. O `LocalExecutor` gerencia instalações em uma única máquina. O `CeleryExecutor` distribui entre nós workers. O `KubernetesExecutor` sobe um pod por tarefa. - **Workers** — Executam o código real das tarefas. Com a nova Task Execution API do Airflow 3.0, os workers se comunicam por meio de um contrato estável, o que permite a execução em contêineres, ambientes edge ou runtimes externos. - **Banco de metadados** — PostgreSQL (recomendado) ou MySQL. Armazena as definições de DAG, os estados das tarefas, os valores XCom, as credenciais de conexão e os logs de auditoria. - **Servidor web** — A interface do Airflow para monitorar as execuções de DAG, inspecionar logs, disparar execuções manuais e gerenciar conexões. > **Escolha do executor em produção** > > Convém evitar o `SequentialExecutor` em produção: ele executa uma única tarefa por vez e existe apenas para desenvolvimento. Para ambientes nativos de Kubernetes, o `KubernetesExecutor` oferece o isolamento mais forte, já que cada tarefa recebe seu próprio pod com recursos e dependências independentes. ## Airflow vs. Prefect vs. Dagster em 2026 O Airflow compete com duas alternativas significativas. A escolha certa depende do tamanho da equipe, da infraestrutura existente e dos tipos de pipelines que estão sendo construídos. | Recurso | Airflow 3.2 | Prefect 3.x | Dagster 1.9 | |---|---|---|---| | **Definição de DAG** | Decoradores Python (`airflow.sdk`) | Decoradores Python (`@flow`, `@task`) | Decoradores Python (`@asset`, `@op`) | | **Agendamento** | Cron, asset-aware, partition-aware | Cron, orientado a eventos | Cron, baseado em sensors, asset-aware | | **Modelo de execução** | Scheduler centralizado + workers distribuídos | Híbrido (servidor + work pools) | dagster-daemon centralizado | | **Tarefas dinâmicas** | Tarefas mapeadas via `.expand()` | Loops Python nativos | Partições dinâmicas | | **Suporte assíncrono** | Nativo na 3.2 | Nativo desde a 2.0 | Operações de E/S assíncronas | | **Isolamento multiequipe** | Integrado (experimental na 3.2) | Baseado em workspaces (Cloud) | Branch deployments | | **Tamanho da comunidade** | O maior (35k+ estrelas no GitHub) | Em crescimento (18k+ estrelas) | Em crescimento (12k+ estrelas) | | **Melhor caso de uso** | Pipelines complexos, multiequipe, com infraestrutura estabelecida | Equipes menores que buscam iteração rápida | Organizações centradas em assets de dados | A vantagem do Airflow está em seu ecossistema: mais de 80 pacotes de providers que cobrem cada serviço de nuvem, banco de dados e API principais. O Prefect se destaca na experiência do desenvolvedor com menos código repetitivo. O modelo asset-centric do Dagster combina com equipes que pensam em termos de produtos de dados em vez de sequências de tarefas. ## Perguntas de entrevista: Apache Airflow para data engineers As perguntas a seguir refletem o que os gestores de contratação e os engenheiros sêniores perguntam durante as entrevistas de data engineering em empresas que rodam o Airflow em produção. **O que é um DAG e como o Airflow o utiliza?** Um DAG (Directed Acyclic Graph) define um workflow como uma coleção de tarefas com dependências, garantido sem referências circulares. O Airflow faz o parse dos arquivos Python da pasta `dags/`, constrói o grafo de dependências e o scheduler determina a ordem de execução. Cada execução de DAG cria um objeto `DagRun` vinculado a uma data lógica. A restrição «acíclico» garante que o scheduler sempre possa encontrar uma ordem de execução válida — a tarefa A executa antes da tarefa B, nunca o contrário ao mesmo tempo. **Como o XCom funciona e quando deve ser evitado?** O XCom (cross-communication) transmite pequenas quantidades de dados entre tarefas. Uma tarefa empurra um valor de retorno para o XCom; as tarefas downstream o recuperam. O Task SDK cuida disso automaticamente ao passar valores de retorno entre tarefas decoradas. O XCom armazena os dados no banco de metadados por padrão, o que o torna inadequado para grandes conjuntos de dados (qualquer coisa acima de alguns KB). Para transferir grandes volumes de dados, convém usar armazenamento externo (S3, GCS) e passar apenas o caminho de referência pelo XCom. **Explique a diferença entre `schedule`, `start_date` e `catchup`.** O parâmetro `schedule` (renomeado de `schedule_interval` no Airflow 3.x) define com que frequência o DAG é executado: uma string cron, um timedelta, um objeto timetable ou um gatilho de asset. O `start_date` define a data lógica mais antiga para a qual uma execução de DAG pode ser criada. `catchup=True` (valor padrão) cria execuções de DAG para todos os intervalos perdidos entre `start_date` e o momento atual. Definir `catchup=False` instrui o scheduler a ignorar os intervalos passados e agendar apenas a partir do tempo atual em diante. Um padrão comum em produção: `catchup=False` para os DAGs operacionais e `catchup=True` para os backfills históricos. **Em que o KubernetesExecutor difere do CeleryExecutor?** O `CeleryExecutor` mantém um pool de processos workers de longa duração conectados por um broker de mensagens (Redis ou RabbitMQ). As tarefas são enfileiradas e executadas nos workers disponíveis. O `KubernetesExecutor` cria um novo pod do Kubernetes para cada tarefa, usando a imagem Docker e os requisitos de recursos da tarefa. O Celery oferece menor latência (sem sobrecarga de inicialização de pod) e funciona bem para cargas homogêneas. O KubernetesExecutor proporciona um isolamento mais forte, controle de recursos por tarefa e elimina a necessidade de gerenciar um pool de workers estático — ideal para cargas heterogêneas em que as tarefas têm requisitos diferentes de dependências e memória. **Quais estratégias existem para lidar com falhas de tarefas?** O Airflow oferece vários mecanismos de tratamento de falhas. `retries` e `retry_delay` configuram novas tentativas automáticas com backoff exponencial. O `on_failure_callback` dispara lógica personalizada (alertas no Slack, incidentes no PagerDuty) quando uma tarefa falha. O `trigger_rule` controla como as tarefas downstream respondem — `all_success` (padrão), `one_success`, `all_failed` ou `none_failed_min_one_success`. Para problemas transitórios de infraestrutura, o parâmetro `retry_exponential_backoff=True` aumenta o tempo de espera entre as tentativas. Os SLAs (agora Deadline Alerts na 3.x) monitoram a duração de execução e disparam callbacks quando as tarefas excedem o tempo de execução esperado. ## Boas práticas de produção para deployments do Airflow Rodar o Airflow de forma confiável em escala exige atenção a vários padrões operacionais que vão além de escrever DAGs corretos. **Tarefas idempotentes.** Cada tarefa deveria produzir o mesmo resultado quando executada várias vezes com as mesmas entradas. Convém usar `INSERT ... ON CONFLICT` ou `MERGE` em vez de um simples `INSERT`. Particionar os dados de saída por data lógica. Isso garante novas tentativas e backfills seguros, sem duplicação de dados. **DAGs pequenos e focados.** Convém resistir à tentação de construir DAGs monolíticos com dezenas de tarefas. Dividir os pipelines complexos em vários DAGs conectados por [assets](https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/assets.html) (antes datasets). DAGs menores fazem parse mais rápido, são mais fáceis de depurar e permitem reinícios parciais do pipeline. **Gerenciamento de conexões.** Armazenar todas as credenciais no gerenciador de conexões do Airflow ou em um backend de secrets externo (AWS Secrets Manager, HashiCorp Vault). Nunca codificar credenciais nos arquivos de DAG. O Airflow 3.x criptografa os campos de conexão em repouso no banco de metadados. **Monitoramento e alertas.** Exportar as métricas do Airflow para o [Prometheus ou StatsD](https://airflow.apache.org/docs/apache-airflow/stable/administration-and-deployment/logging-monitoring/metrics.html). Acompanhar `scheduler_heartbeat`, `dag_processing.total_parse_time` e `executor.queued_tasks`. O Airflow 3.2 adiciona traces do OpenTelemetry para uma observabilidade de pipeline de ponta a ponta. Preparando uma entrevista de data engineering que cobre a orquestração de pipelines? A SharpSkill oferece [perguntas de entrevista do Airflow](/technologies/data-engineering/interview-questions/airflow-fundamentals) dedicadas e módulos de prática que reproduzem cenários reais de ambientes de produção. ## Conclusão - O Airflow 3.2 introduz o Task SDK (`airflow.sdk`) como API estável para a escrita de DAG — convém migrar as importações agora para evitar rupturas em versões futuras - As partições de assets habilitam um agendamento data-aware no nível da partição, eliminando os disparos de pipeline redundantes em atualizações de dados parciais - O suporte assíncrono nativo no PythonOperator lida com cargas intensivas em E/S (downloads em lote, fan-outs de API) sem operadores deferrable personalizados - O mapeamento dinâmico de tarefas via `.expand()` se adapta ao tamanho variável das cargas em tempo de execução, sem alterações no código do DAG - A preparação para entrevistas deve cobrir o funcionamento dos DAGs, os trade-offs entre executors (Celery vs. Kubernetes), as limitações do XCom e os padrões de idempotência - Os deployments de produção se beneficiam de DAGs pequenos e idempotentes, de um gerenciamento de secrets externo e da exportação de métricas para plataformas de observabilidade --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pt/blog/data-engineering/apache-airflow-pipeline-orchestration-dags-interview-2026