O Modelo Mental de Batch, Streaming e Orquestração
Todo pipeline de dados, não importa qual ferramenta o construa, está respondendo às mesmas três perguntas.
Busque em todas as páginas da documentação
Todo pipeline de dados, não importa qual ferramenta o construa, está respondendo às mesmas três perguntas.
Quanta quantidade de dados um único run deste pipeline processa - um chunk delimitado, ou um stream ilimitado e contínuo?
O que decide quando e em qual ordem cada etapa deste pipeline é executada?
E o que acontece na segunda vez que uma etapa é executada com a mesma entrada, seja por causa de um retry, um backfill ou uma mensagem redelivrada?
Noções Básicas de Engenharia de Dados mostra a API concreta para construir jobs batch e de streaming; esta página é sobre os três conceitos por trás de cada um deles - batch versus streaming como um trade-off, o DAG como um grafo de dependência em vez de um schedule, e idempotência como a propriedade que torna a recuperação de falhas segura.
Um pipeline batch processa um conjunto de dados delimitado e de tamanho conhecido - "pedidos de ontem", "arquivos de log deste mês" - e termina; executá-lo novamente mais tarde processa o próximo chunk delimitado.
Um pipeline streaming processa uma sequência ilimitada de eventos à medida que eles chegam, sem um "fim" natural para esperar, o que significa que ele tem que produzir resultados úteis continuamente em vez de após uma passagem completa pelos dados.
Este é um trade-off genuíno, não apenas duas implementações da mesma ideia: batch pode olhar todos os dados antes de decidir uma resposta (um total do dia completo, um join completo), enquanto streaming tem que responder apenas com o que chegou até agora, aceitando que dados que chegam atrasados podem precisar ser reconciliados depois.
Um DAG (directed acyclic graph) é a segunda ideia central: é um grafo de tarefas e dependências - "tarefa B precisa da saída da tarefa A" - sem ciclos, e criticamente, um DAG define o que depende do quê, não quando as coisas rodam.
Uma leitura comum equivocada é pensar em um DAG como uma sequência fixa, como uma lista numerada de etapas; na realidade, um scheduler (agendador) é livre para executar quaisquer duas tarefas sem dependência entre elas em paralelo, ou em qualquer ordem, desde que as dependências declaradas de cada tarefa sejam concluídas primeiro.
Orquestração é a camada que transforma uma definição de DAG em execução real: ela decide quais tarefas estão prontas para rodar (suas dependências foram satisfeitas), retenta tarefas falhas e rastreia o estado de cada run - isso é distinto do agendamento (scheduling) simples, que apenas decide quando um job começa, sem noção de dependência entre jobs.
Idempotência é a propriedade de que executar uma operação duas vezes com a mesma entrada produz o mesmo resultado como executá-la uma vez - e é a propriedade que torna cada retry, backfill e mensagem redelivrada segura em vez de perigosa.
A escolha batch/streaming e o requisito de idempotência estão mais conectados do que parecem inicialmente: qualquer sistema de streaming que promete entrega confiável sob falha precisa redelivrar mensagens às vezes, e apenas o processamento idempotente torna essa redelivração inofensiva em vez de duplicar dados.
Sistemas de streaming oferecem principalmente entrega at-least-once (pelo menos uma vez) por padrão - uma mensagem pode ser processada mais de uma vez após uma falha e reinício, porque confirmar "eu processei isso" e "commit o resultado" não pode ser tornado perfeitamente atômico entre dois sistemas diferentes (o message broker e o sink de saída) sem coordenação extra.
O processamento exactly-once (exatamente uma vez), onde é alegado, é geralmente alcançado combinando entrega at-least-once com um sink idempotente - por exemplo, escrevendo resultados com chave por um ID de mensagem para que uma escrita duplicada simplesmente sobrescreva a mesma linha em vez de adicionar uma segunda - não por alguma garantia de nível inferior de que duplicatas nunca ocorrem.
Um watermark é como os sistemas de streaming raciocinam sobre "feito o suficiente": já que um stream nunca termina de verdade, um watermark é uma afirmação heurística de que todos os dados até algum ponto no tempo do evento provavelmente chegaram, permitindo que agregações em janelas (como "eventos por janela de 5 minutos") finalizem um resultado enquanto aceitam que uma pequena fração de dados muito atrasados pode ser perdida ou tratada separadamente.
Orquestradores batch enfrentam uma versão paralela do mesmo problema de idempotência: se um job noturno travar no meio e for retentado, anexar sua saída parcial uma segunda vez duplicaria as contagens de linhas - a correção padrão é fazer a saída de cada run ser chaveada por uma partição estável (uma data, um ID de batch) e ter o job sobrescrever essa partição em vez de anexar cegamente.
Orquestradores baseados em DAG (Airflow, Prefect, Dagster) também codificam quanta história um run de tarefa "pertence" através de um data interval (intervalo de dados) - o intervalo de tempo lógico que um run representa - que é o que permite que um backfill reexecute os runs do DAG do mês passado e obtenha os dados do mês passado de volta, em vez de acidentalmente processar os dados de hoje sob o rótulo de ontem.
# um DAG expressa dependência, não ordem de execução:
# extract_orders e extract_customers não têm dependência um do outro,
# então um orquestrador é livre para executá-los concorrentemente
extract_orders >> transform_orders
extract_customers >> transform_orders # transform espera por AMBAS as tarefas upstream
transform_orders >> load_warehouse # load só começa quando transform terminaEm escala, a escolha batch versus streaming deixa de ser binária e se torna um espectro: sistemas de micro-batch (structured streaming no PySpark, por exemplo) processam chunks delimitados pequenos e frequentes, trocando parte da latência do streaming pela lógica mais simples de dados delimitados do batch.
Escolher entre Airflow, Prefect e Dagster é menos sobre qual engine de DAG é "melhor" e mais sobre qual unidade de abstração corresponde ao modelo mental da equipe - Airflow se concentra em tarefas e operadores, Prefect se concentra em funções Python simples com anotações leves, e Dagster se concentra em ativos de dados (as saídas que um pipeline produz) em vez das tarefas que os produzem.
A validação de dados pertence como um nó de primeira classe no DAG, não como um pensamento posterior: um pipeline que carrega dados ruins em um schedule é muitas vezes pior do que um que falha ruidosamente, porque consumidores downstream (dashboards, features de ML, outros pipelines) podem confiar na saída sem saber que ela está errada.
A observabilidade para pipelines tem que responder perguntas que o monitoramento batch e o monitoramento de streaming fazem de forma diferente: batch pergunta "este run terminou, e como suas contagens de linhas se comparam ao histórico", enquanto streaming pergunta "quão atrasado está este consumidor" (consumer lag) e "quantas mensagens estão presas em uma fila de mensagens mortas (dead-letter queue)".
A escolha do formato de arquivo interage com tudo isso: formatos colunares como Parquet suportam poda de partições (partition pruning) e pushdown de predicados que tornam os padrões de sobrescrita de partição idempotentes baratos, enquanto formatos orientados a linhas tornam o reprocessamento seletivo de apenas uma partição muito mais caro.
| Abordagem | Força | Fraqueza | Melhor Ajuste |
|---|---|---|---|
| Batch | Raciocínio simples, pode ver todos os dados antes de responder, backfills fáceis | Latência medida em minutos-a-horas; obsoleto por definição entre runs | Relatórios agendados, backfills históricos, agregação não crítica em tempo |
| Micro-batch | Une a simplicidade do batch com entrega quase em tempo real | Ainda adiciona um piso de latência de agendamento/trigger; não verdadeiramente orientado a eventos | Dashboards quase em tempo real onde latência de segundos-a-minutos é aceitável |
| Streaming | Menor latência, reage a eventos individuais | Requer watermarks/windowing, mais difícil de raciocinar sobre "feito", sobrecarga de gerenciamento de estado | Detecção de fraude, alertas em tempo real, arquiteturas orientadas a eventos |
| Orquestração DAG (Airflow/Prefect/Dagster) | Grafo de dependência explícito, retries, backfills, agendamento em um único sistema | Adiciona um sistema operacional para rodar e monitorar; exagero para um script linear simples | Pipelines multi-etapas com dependências reais entre tarefas em várias fontes |
Não diretamente - um DAG define dependências entre tarefas, e um orquestrador é livre para executar quaisquer duas tarefas sem dependência entre elas concorrentemente ou em qualquer ordem, desde que todas as dependências upstream declaradas de cada tarefa tenham sido concluídas primeiro.
Agendamento decide quando um job começa (um trigger tipo cron), enquanto orquestração adicionalmente rastreia dependências entre tarefas, retenta falhas e gerencia o estado da execução de um DAG inteiro - um agendador sem modelo de dependência não é um orquestrador.
Falhas são rotineiras em pipelines distribuídos - workers travam, redes particionam, mensagens são redelivradas - e idempotência é o que transforma "esta tarefa rodou duas vezes" de um evento que corrompe dados para um no-op inofensivo, que é o que torna retries automáticos e backfills seguros para executar sem limpeza manual.
Um watermark é uma afirmação heurística de que todos os eventos até um certo ponto no tempo do evento provavelmente chegaram, o que permite que uma agregação em janela (como uma contagem de 5 minutos) finalize e emita um resultado em vez de esperar para sempre por dados que teoricamente ainda podem chegar atrasados.
Escrevendo a saída escopada para uma chave de partição estável - uma data, um ID de run, um data interval - e sobrescrevendo essa partição em vez de anexá-la, de modo que um run retentado substitua sua própria saída anterior (possivelmente parcial) em vez de duplicar linhas ao lado dela.
Airflow centra seu modelo em tarefas e operadores conectados em um DAG; Prefect centra em funções Python comuns com decoração leve para rastreamento de dependências; Dagster centra nos ativos de dados que um pipeline produz em vez das tarefas que os produzem - todos os três ainda orquestram DAGs de trabalho dependente por baixo.
Micro-batch se encaixa quando a saída quase em tempo real importa (segundos-a-minutos, não horas), mas a equipe quer continuar raciocinando sobre pequenos chunks delimitados em vez de construir infraestrutura de streaming completa com watermarks e consumidores stateful de longa duração.
Um pipeline que "bem-sucedido" enquanto carrega dados inválidos, incompletos ou duplicados é muitas vezes mais prejudicial do que um que falha ruidosamente, porque os consumidores downstream não têm sinal para desconfiar da saída - é por isso que a validação de dados é tratada como um nó de DAG com seu próprio estado de aprovação/falha, não uma verificação lateral.
Consumer lag é a lacuna entre a última mensagem produzida para um stream e a última mensagem que um determinado consumidor processou; um lag crescente significa que o consumidor não consegue acompanhar o volume de entrada, o que é um sinal de alerta precoce antes que um pipeline visivelmente fique para trás ou perca dados.
Apenas no sentido trivial de que uma sequência estrita é tecnicamente um grafo de dependência (linear) - o valor prático de um orquestrador DAG real aparece quando existem branches genuinamente independentes que poderiam rodar em paralelo, ou tarefas que precisam de retries, backfills e agendamento ciente de dependências que um script simples não tem framework para.
Formatos colunares como Parquet suportam poda de partições, então sobrescrever ou reprocessar apenas uma partição (uma data, um intervalo de chaves) toca apenas os arquivos relevantes; formatos orientados a linhas como CSV geralmente exigem reescrita ou varredura de um arquivo inteiro mesmo para corrigir uma partição, tornando o reprocessamento parcial idempotente muito mais caro.
Versões do Stack: Esta página foi escrita para Python 3.14 (estável) / 3.13 (manutenção); os conceitos (batch/streaming, DAGs, idempotência) são agnósticos de ferramenta e não estão atrelados a uma versão específica de orquestrador ou biblioteca de processamento de stream.
Revisado por Chris St. John·Última atualização: 15 de jul. de 2026