Contextualização
Com o crescimento exponencial da geração de dados, surgiu o conceito de Big Data, que trata dos desafios de armazenar, processar e extrair valor de grandes volumes de dados de forma eficiente.
Dentro desse contexto, existem duas principais formas de processar dados em larga escala:
- Processamento em tempo real (stream processing)
- Processamento em lote (batch processing)
Ambas possuem propósitos distintos e sua escolha depende diretamente do contexto de aplicação.
| Comparativo | Batch Processing | Stream Processing |
| Natureza do processamento | Dados são acumulados e processados em massa | Dados são processados conforme sua chegada |
| Frequência de execução | Agendada (hora, dia, semana, mês) | Contínua |
| Casos de uso | Relatórios, ETLs e reconciliação de dados | Monitoramento, detecção de fraude e alertas |
| Tempo de processamento normalmente encontrado | Minutos ou horas | Milissegundos ou segundos |
Aplicações Batch
O processamento em lote possui um conjunto próprio de características e desafios:
- Execução por fases bem definidas — O processo batch segue um ciclo previsível: inicia, processa e termina. Essa estrutura facilita a previsibilidade e o controle da execução.
- Ausência de interface com o usuário — Os batches são executados automaticamente, geralmente por meio de um orquestrador (como Spring Scheduler, Quartz ou Airflow), sem interação direta do usuário.
- Saída assíncrona — Como o processamento não ocorre em tempo real, os resultados são disponibilizados posteriormente. Assim, o foco está no throughput (quantidade de dados processados por unidade de tempo), e não na latência (tempo de resposta).
De acordo com Martin Kleppmann, em seu livro Designing Data-Intensive Applications, os sistemas podem ser classificados em três categorias:
Online — Respondem a requisições em tempo real, priorizando a latência.
Exemplos: APIs REST, aplicações web, bancos de dados transacionais.
Near Real-Time (quase em tempo real) — Combinam aspectos de batch e stream, processando eventos à medida que ocorrem, com baixa latência, mas não imediata.
Exemplos: sistemas de recomendação, atualização de dashboards, stream processors (Kafka Streams, Flink).
Offline — Processam grandes volumes de dados acumulados, geralmente em execuções agendadas. O foco está no throughput.
Exemplos: geração de relatórios, ETL em data warehouses, reconciliações financeiras.
As aplicações batch se enquadram como sistemas offline.
Por que Aplicações Batch ainda são relevantes?
Apesar do avanço do stream processing, o batch continua amplamente utilizado, especialmente em cenários onde:
- Os dados não precisam ser processados imediatamente.
- Há vantagens de custo (máquinas podem ser desligadas após o processamento ou reaproveitadas para outras aplicações).
Modelos de Aplicações Batch
As aplicações batch podem ser divididas em três modelos, de acordo com a origem dos dados de entrada:
- Database-driven — Dados consumidos a partir de um banco de dados.
- File-driven — Dados consumidos a partir de arquivos.
- Message-driven — Dados consumidos a partir de brokers de mensagens.
Curiosidade
Um dos algoritmos mais notórios nesse contexto é o MapReduce, popularizado pelo Google em 2004 para viabilizar o processamento massivo de dados.
Esse modelo inspirou frameworks como Apache Hadoop e Apache Spark.
Hoje existem diversos frameworks para desenvolvimento de aplicações batch, sendo o Spring Batch um dos mais utilizados.
Spring Batch
O Spring Batch é um framework robusto para o desenvolvimento de aplicações batch. Ele faz parte do ecossistema Spring Framework.
Ele oferece:
- Ferramentas para leitura, processamento e saída de dados.
- Tratamento de falhas e reinício automático.
- Monitoramento e controle de execução.
- Formas padronizadas de escalabilidade.
Importante: o Spring Batch depende de um banco relacional para persistência dos metadados de execução.
Características
O Spring Batch possui diversas características que permitem ao desenvolvedor:
- Modelar fluxos de processamento em lote de forma estruturada, com Jobs e Steps.
- Processar dados em blocos (chunk-oriented processing), garantindo eficiência e controle de transações em grandes volumes de dados.
- Controlar o estado e reiniciar execuções (restartability), retomando o processamento a partir do ponto de falha.
- Gerenciar transações automaticamente, assegurando consistência mesmo em cenários de falha.
- Escalar e paralelizar tarefas, em múltiplas threads, processos ou ambientes distribuídos (via Spring Cloud).
- Personalizar fluxos e componentes (leitores, escritores, processadores, políticas de retry/skip).
- Tratar erros de forma robusta, definindo políticas de retentativa, ignorando registros problemáticos ou interrompendo a execução.
- Integrar com diferentes fontes de dados, como bancos relacionais, arquivos (CSV, XML, JSON), filas de mensagens ou serviços externos.
- Monitorar e auditar execuções, fornecendo métricas detalhadas e rastreabilidade.
Fundamentos
A arquitetura do Spring Batch é dividida em três camadas:
- Application — Código customizado do desenvolvedor.
- Core — Contém os elementos necessários para executar uma aplicação batch.
- Infrastructure — Fornece ferramentas de suporte ao desenvolvimento.
Linguagem de domínio
Principais conceitos do Spring Batch:
- Job — Representa o processo batch.
- JobInstance — Execução lógica única de um job.
- JobParameters — Parâmetros utilizados em uma execução.
- JobExecution — Representa cada execução de um job (status, início, fim etc.).
- Step — Etapa individual de um job.
- StepExecution — Execução técnica de um step.
- ExecutionContext — Armazena informações auxiliares durante a execução.
Esses conceitos são representados por objetos e persistidos nas tabelas de metadados do Spring Batch.
Componentes funcionais
Componentes principais disponibilizados pelo framework:
- JobLauncher — Inicia a execução de um job.
- JobRepository — Gerencia estado e persistência de metadados.
- ItemReader — Responsável por ler os dados de entrada.
- ItemProcessor — Aplica lógica de negócio (transformar, validar, descartar).
- ItemWriter — Escreve os dados processados na saída (arquivos, banco, etc.).
Estratégias de execução
O Spring Batch suporta duas estratégias de execução:
- Tasklet — Indicado para processamentos simples e diretos (ex.: verificação de diretórios, tarefas de preparação).
- Chunking — Indicado para grandes volumes, otimizando uso de CPU e memória. Esse é o modelo mais utilizado em batches complexos.
Exemplos de implementação
No repositório abaixo, são implementados dois jobs:
- Tasklet — Um simples HelloWorld.
- Chunking — Processamento de um arquivo CSV com persistência em banco de dados.
Esses exemplos podem servir como base para construção de batches mais complexos.
📂 Repositório: spring-batch-handson