Nota de atualização (2026): este artigo revisita conceitos da minha jornada de aprendizado de Apache Spark e os conecta aos ambientes modernos de implantação. Algumas opções de execução, integrações e recomendações surgiram ou evoluíram depois dos primeiros anos do projeto.
Nos nove artigos anteriores, exploramos a arquitetura do Apache Spark por diferentes perspectivas.
Aprendemos que uma aplicação Spark possui um Driver, que coordena o processamento, e Executors, responsáveis por executar Tasks sobre partições de dados.
Também vimos que o Spark organiza o trabalho em Jobs, Stages e Tasks, utiliza shuffle para redistribuir dados, gerencia memória, mantém lineage para recuperação de falhas e oferece mecanismos como Broadcast Variables e Accumulators.
Mas existe uma pergunta que ainda não respondemos completamente:
Onde o Driver realmente executa quando enviamos uma aplicação Spark para um cluster?
E uma segunda pergunta igualmente importante:
Quem inicia, gerencia e encerra os Executors?
Essas questões nos levam a três conceitos fundamentais:
- Deployment Mode.
- Cluster Manager.
- Application Submission.
Vamos entender como eles se relacionam e por que essa distinção é essencial para desenvolver, implantar e operar aplicações Spark em produção.
1. O que acontece quando executamos uma aplicação Spark?
Considere uma aplicação PySpark:
from pyspark.sql import SparkSession
from pyspark.sql.functions import col
spark = (
SparkSession.builder
.appName("VendasAnalytics")
.getOrCreate()
)
vendas = spark.read.parquet(
"/data/vendas"
)
resultado = (
vendas
.filter(col("ano") == 2026)
.groupBy("estado")
.sum("valor")
)
resultado.show()
spark.stop()
O código parece simples.
Mas, dependendo de onde executamos a aplicação, existe uma infraestrutura por trás:
APPLICATION
|
v
DRIVER
|
v
CLUSTER MANAGER
|
+---------+---------+
| | |
v v v
EXECUTOR 1 EXECUTOR 2 EXECUTOR 3
| | |
TASKS TASKS TASKS
O Driver coordena o processamento.
O Cluster Manager participa da alocação e do gerenciamento dos recursos necessários.
Os Executors realizam o trabalho distribuído.
A localização e o ciclo de vida desses componentes dependem do ambiente de implantação.
2. Driver, Executor e Cluster Manager não são a mesma coisa
Antes de falar sobre Client Mode e Cluster Mode, precisamos separar três responsabilidades.
Driver
O Driver é o processo que coordena a aplicação Spark.
Entre suas responsabilidades estão:
- Executar o programa principal.
- Construir e coordenar operações Spark.
- Planejar Jobs e Stages.
- Agendar Tasks.
- Acompanhar resultados e falhas.
- Interagir com os Executors.
Executor
Os Executors são processos associados à aplicação Spark que executam Tasks e armazenam dados intermediários ou persistidos conforme necessário.
Eles utilizam recursos como CPU, memória, disco e rede.
Cluster Manager
O Cluster Manager gerencia recursos computacionais do ambiente.
Dependendo da plataforma, ele pode ser responsável por alocar containers, Pods ou processos para os componentes Spark.
Uma visão simplificada:
Driver
|
| Solicita recursos e coordena execução
|
v
Cluster Manager
|
| Disponibiliza recursos
|
v
Executors
|
| Executam Tasks
|
v
Distributed Processing
É importante lembrar que o Cluster Manager não substitui o scheduler interno do Spark.
O Spark continua responsável por organizar e distribuir suas Tasks entre os Executors disponíveis.
3. O que é Deployment Mode?
Deployment Mode define, principalmente, onde o processo Driver será executado em relação ao ambiente que submete a aplicação.
Os dois modos mais conhecidos são:
Client Mode
e:
Cluster Mode
Essa distinção parece pequena, mas afeta diretamente:
- Conectividade.
- Logs.
- Disponibilidade do Driver.
- Empacotamento da aplicação.
- Operação em produção.
- Diagnóstico de falhas.
Vamos começar pelo Client Mode.
4. Client Mode
No Client Mode, o Driver executa no ambiente de onde a aplicação é submetida.
Imagine que estamos utilizando uma máquina de desenvolvimento ou um servidor de borda para executar:
spark-submit \
--deploy-mode client \
app.py
Em um ambiente de cluster compatível, a arquitetura conceitual é:
MÁQUINA DE SUBMISSÃO
+-------------------+
| |
| DRIVER |
| |
+---------+---------+
|
| Comunicação
|
v
CLUSTER MANAGER
|
+---------+---------+
| | |
v v v
EXECUTOR 1 EXECUTOR 2 EXECUTOR 3
O Driver permanece no processo de submissão.
Os Executors podem executar em outros nós.
Isso significa que o Driver precisa conseguir se comunicar adequadamente com os Executors e com os serviços relevantes do cluster.
5. Por que Client Mode é útil?
Client Mode costuma ser conveniente em cenários como:
- Desenvolvimento interativo.
- Depuração.
- Sessões de notebooks.
- Execução a partir de servidores de borda.
- Aplicações nas quais desejamos acompanhar diretamente a saída do Driver.
Imagine que estamos investigando um pipeline.
Queremos observar mensagens como:
Starting Spark application...
Loading dataset...
Executing aggregation...
Writing output...
Application finished.
No Client Mode, a saída do Driver normalmente fica associada ao ambiente de submissão.
Isso facilita determinados fluxos de desenvolvimento e troubleshooting.
Mas também traz responsabilidades.
6. A máquina cliente faz parte da execução
Um erro comum é imaginar:
Enviei a aplicação para o cluster. Agora minha máquina não importa mais.
Em Client Mode, isso não é verdade.
O Driver continua executando no ambiente cliente.
Se esse processo for encerrado, a aplicação poderá ser interrompida.
Considere:
Developer Laptop
|
v
Driver
|
v
Cluster
Se o laptop for desligado ou o processo Driver terminar, não devemos assumir que a aplicação continuará normalmente.
O comportamento exato depende do ambiente e de seus mecanismos de supervisão, mas o princípio permanece:
O Driver é parte ativa da aplicação.
7. Client Mode e conectividade
Outra consequência importante é a rede.
Os Executors precisam se comunicar com o Driver.
Imagine:
Developer Laptop
|
| VPN / Firewall / NAT
|
v
Spark Cluster
Se os Executors não conseguem alcançar o endereço anunciado pelo Driver, a aplicação pode falhar mesmo que exista CPU e memória disponíveis.
Problemas comuns incluem:
- Endereço incorreto do Driver.
- DNS.
- Firewall.
- Portas bloqueadas.
- NAT.
- Instabilidade de VPN.
- Interfaces de rede configuradas incorretamente.
Em ambientes corporativos, essa é uma das razões para utilizar servidores de borda ou plataformas de notebooks integradas ao cluster.
8. Cluster Mode
Agora vamos mudar a localização do Driver.
No Cluster Mode, o Driver é executado dentro do ambiente gerenciado pelo cluster, conforme os mecanismos da plataforma utilizada.
Conceitualmente:
MÁQUINA DE SUBMISSÃO
+-------------------+
| |
| spark-submit |
| |
+---------+---------+
|
| Submete aplicação
|
v
CLUSTER MANAGER
|
+---------+---------+
| |
v v
DRIVER EXECUTORS
| |
+---------+---------+
|
v
DISTRIBUTED JOB
A diferença central é:
O Driver não precisa permanecer no processo cliente que iniciou a submissão.
Isso torna o Cluster Mode adequado a muitos cenários de execução automatizada.
9. Cluster Mode é melhor para produção?
Frequentemente, Cluster Mode é uma escolha conveniente para Jobs batch de produção.
Mas não devemos transformar isso em uma regra absoluta.
Existem plataformas gerenciadas e arquiteturas específicas em que o ciclo de vida da aplicação é controlado de outras maneiras.
O importante é compreender os requisitos.
Por exemplo:
Pipeline noturno
|
v
Scheduler
|
v
Application Submission
|
v
Cluster-managed Driver
|
v
Executors
Nesse cenário, não queremos depender de uma sessão interativa de desenvolvimento para manter a aplicação ativa.
Cluster Mode ajuda a separar o ambiente de submissão do ambiente de execução.
10. Client Mode vs. Cluster Mode
| Característica | Client Mode | Cluster Mode |
|---|---|---|
| Localização do Driver | Ambiente de submissão | Ambiente gerenciado pelo cluster |
| Uso frequente | Desenvolvimento e sessões interativas | Jobs automatizados e batch |
| Logs do Driver | Próximos ao processo cliente | Normalmente obtidos pela plataforma |
| Dependência do cliente | Driver permanece no cliente | Submissão pode terminar sem encerrar necessariamente a aplicação |
| Conectividade | Executors precisam alcançar o Driver cliente | Driver executa na rede do cluster |
| Disponibilidade | Depende do processo Driver cliente | Depende do cluster e da supervisão |
| Melhor escolha | Depende do cenário | Depende do cenário |
O ponto principal é:
Client Mode e Cluster Mode descrevem a localização do Driver, não a quantidade de dados processados nem o grau de paralelismo da aplicação.
11. Deployment Mode não é Cluster Manager
Agora precisamos evitar outra confusão.
Deployment Mode responde:
Onde o Driver executa?
Cluster Manager responde:
Qual sistema gerencia os recursos do ambiente?
São dimensões diferentes.
Por exemplo, dependendo do suporte da plataforma, podemos encontrar combinações como:
YARN + Client Mode
YARN + Cluster Mode
Kubernetes + Client Mode
Kubernetes + Cluster Mode
Standalone + Client Mode
Standalone + Cluster Mode
Entretanto, a disponibilidade de cada combinação depende do Cluster Manager, da linguagem e da versão do Spark.
Em particular, o suporte a aplicações Python em Standalone Cluster Mode possui restrições documentadas em versões do Spark. Portanto, não devemos presumir que todas as combinações funcionam igualmente.
12. Spark Standalone
Spark Standalone é o gerenciador de cluster próprio do Apache Spark.
Sua arquitetura clássica envolve:
STANDALONE MASTER
|
+---------+---------+
| | |
v v v
WORKER 1 WORKER 2 WORKER 3
| | |
v v v
EXECUTOR EXECUTOR EXECUTOR
O Master coordena a disponibilidade dos recursos do cluster Standalone.
Os Workers disponibilizam recursos computacionais.
O Driver e os Executors são iniciados conforme o modo de implantação e os recursos disponíveis.
Esse modelo é útil para compreender a arquitetura do Spark sem adicionar toda a complexidade de um gerenciador externo.
13. Spark em YARN
YARN significa:
Yet Another Resource Negotiator.
Ele faz parte do ecossistema Hadoop e gerencia recursos para aplicações distribuídas.
Uma visão simplificada:
YARN
|
ResourceManager
|
+----------+----------+
| | |
v v v
NodeManager NodeManager NodeManager
| | |
v v v
Containers Containers Containers
O Spark pode utilizar esses recursos para executar seus componentes.
No YARN, existe também o conceito de ApplicationMaster, cujo papel e relacionamento com o Driver variam conforme o deployment mode.
14. YARN Client Mode
No YARN Client Mode, o Driver executa no ambiente cliente.
Conceitualmente:
CLIENT MACHINE
+------------+
| DRIVER |
+-----+------+
|
v
YARN CLUSTER
|
ApplicationMaster
|
+------+------+
| |
v v
Executor 1 Executor 2
O ApplicationMaster participa do gerenciamento dos recursos da aplicação no YARN.
O Driver permanece no cliente.
Esse detalhe é importante ao interpretar logs e falhas.
15. YARN Cluster Mode
No YARN Cluster Mode, o Driver executa no cluster, dentro do contexto da aplicação gerenciada pelo YARN.
Uma visão conceitual:
SUBMISSION CLIENT
|
v
YARN CLUSTER
|
v
ApplicationMaster
+--------------+
| DRIVER |
+------+-------+
|
+------+------+
| |
v v
Executor 1 Executor 2
Nesse modo, o Driver não depende de continuar executando na máquina que fez a submissão.
Para workloads batch, isso frequentemente simplifica a operação.
16. Spark em Kubernetes
Kubernetes utiliza uma arquitetura baseada em recursos como Pods, Deployments, Services e outros objetos.
No Spark, podemos executar o Driver e os Executors em Pods.
Uma visão típica de Cluster Mode:
spark-submit
|
v
KUBERNETES API
|
v
DRIVER POD
|
v
EXECUTOR PODS
/ | \
v v v
Exec 1 Exec 2 Exec 3
O Driver solicita os recursos necessários por meio da integração Spark com Kubernetes.
Os Executors executam em Pods associados à aplicação.
Isso facilita a integração com práticas modernas de infraestrutura containerizada.
17. Kubernetes não elimina a arquitetura do Spark
É importante compreender:
Kubernetes
não substitui:
Spark DAG Scheduler
nem:
Spark Task Scheduler
O Kubernetes gerencia recursos e o ciclo de vida dos Pods.
O Spark continua responsável por:
- Construir planos de execução.
- Organizar Jobs e Stages.
- Distribuir Tasks.
- Coordenar Executors.
- Gerenciar shuffle e recomputação.
Podemos pensar:
Kubernetes
|
v
Resource Orchestration
|
v
Spark Application
|
v
Distributed Data Processing
São responsabilidades complementares.
18. E o modo local?
Antes de utilizar um cluster real, podemos executar Spark localmente.
Por exemplo:
spark = (
SparkSession.builder
.master("local[*]")
.appName("SparkLocal")
.getOrCreate()
)
O parâmetro:
local[*]
indica que o Spark pode utilizar os núcleos lógicos disponíveis na máquina local.
Também podemos utilizar:
local[2]
para configurar dois threads de execução local.
Exemplo:
spark = (
SparkSession.builder
.master("local[2]")
.appName("SparkLocal")
.getOrCreate()
)
Isso é útil para desenvolvimento e experimentação.
Mas precisamos lembrar que uma execução local não reproduz integralmente:
- Latência de rede entre nós.
- Comportamento de um cluster real.
- Falhas distribuídas.
- Restrições de containers.
- Escalabilidade de armazenamento.
- Dinâmica de alocação de recursos.
Portanto, testes locais são importantes, mas não substituem validação no ambiente de destino.
19. O que é spark-submit?
spark-submit é a ferramenta de submissão de aplicações Spark.
Ela permite informar:
- Aplicação.
- Cluster Manager.
- Deployment Mode.
- Recursos.
- Configurações.
- Dependências.
- Argumentos da aplicação.
A estrutura geral é:
spark-submit \
--master <MASTER> \
--deploy-mode <MODE> \
--conf <KEY=VALUE> \
app.py
Os valores exatos dependem do ambiente.
20. Exemplo local com spark-submit
Vamos criar uma aplicação simples.
Arquivo:
app.py
Conteúdo:
from pyspark.sql import SparkSession
from pyspark.sql.functions import col
spark = (
SparkSession.builder
.appName("ExemploSparkSubmit")
.getOrCreate()
)
dados = spark.range(1, 1_000_001)
resultado = dados.filter(
col("id") % 2 == 0
)
print(
"Quantidade de números pares:",
resultado.count()
)
spark.stop()
Executamos:
spark-submit \
--master "local[*]" \
app.py
Resultado esperado:
Quantidade de números pares: 500000
Esse exemplo é suficiente para compreender a estrutura básica de uma submissão.
21. Exemplo de submissão para YARN
Em um ambiente YARN configurado:
spark-submit \
--master yarn \
--deploy-mode cluster \
--driver-memory 4g \
--executor-memory 8g \
--executor-cores 2 \
--num-executors 4 \
app.py
Aqui estamos solicitando uma aplicação com determinados recursos.
Mas atenção:
Esses valores são ilustrativos, não uma recomendação universal de dimensionamento.
O tamanho adequado depende de:
- Volume de dados.
- Tipo de operação.
- Quantidade de partições.
- Shuffle.
- Memória.
- Concorrência.
- Limites do cluster.
Esse raciocínio conecta diretamente a Parte 7.
22. Exemplo de submissão para Kubernetes
Em um ambiente Kubernetes com Spark configurado, uma submissão pode seguir este formato:
spark-submit \
--master k8s://https://K8S_API_SERVER:6443 \
--deploy-mode cluster \
--name spark-example \
--conf spark.kubernetes.container.image=REGISTRY/SPARK_IMAGE:TAG \
--conf spark.executor.instances=3 \
local:///opt/spark/app.py
Os valores são placeholders e precisam ser substituídos pelos recursos reais do ambiente.
Observe:
k8s://
que identifica a integração com Kubernetes.
E:
local:///opt/spark/app.py
que, nesse exemplo, indica um arquivo disponível dentro da imagem/container utilizado na execução.
A imagem precisa conter a aplicação nesse caminho, além de estar preparada para executar Spark corretamente.
23. --master e --deploy-mode
Esses dois parâmetros merecem atenção especial.
--master
Indica o ambiente de execução ou o gerenciador de cluster.
Exemplos:
local[*]
spark://HOST:7077
yarn
k8s://https://HOST:6443
--deploy-mode
Indica a localização do Driver.
Exemplos:
client
cluster
Portanto:
--master yarn \
--deploy-mode cluster
significa:
Utilizar YARN como Cluster Manager e executar o Driver no ambiente do cluster.
São decisões relacionadas, mas distintas.
24. O que acontece depois do spark-submit?
Uma sequência conceitual:
1. spark-submit
|
v
2. Application Submission
|
v
3. Driver Initialization
|
v
4. SparkSession / SparkContext
|
v
5. Resource Allocation
|
v
6. Executors Available
|
v
7. Action Triggered
|
v
8. Job Created
|
v
9. Stages Planned
|
v
10. Tasks Scheduled
|
v
11. Distributed Execution
|
v
12. Results / Writes
|
v
13. Application Completion
A ordem exata de alguns eventos depende do Cluster Manager e do modo de implantação.
Mas essa sequência ajuda a conectar submissão e execução distribuída.
25. O Driver precisa acessar os dados?
Essa pergunta merece cuidado.
O Driver normalmente coordena o processamento, mas a leitura distribuída de grandes datasets é realizada pelos Executors.
Ainda assim, dependendo do código e das fontes utilizadas, o Driver pode precisar acessar:
- Metadados.
- Catálogos.
- Configurações.
- Endpoints de serviços.
- Informações de schema.
- Caminhos e credenciais.
- Recursos necessários para planejamento.
Não devemos assumir que apenas os Executors precisam de conectividade com os sistemas externos.
A arquitetura precisa considerar o acesso de cada componente.
26. O erro clássico de caminhos locais
Imagine uma aplicação:
df = spark.read.csv(
"/home/usuario/dados.csv"
)
Ela funciona no notebook local.
Depois enviamos para um cluster.
Agora os Executors estão em outras máquinas.
O caminho:
/home/usuario/dados.csv
pode não existir nesses nós.
O problema não está necessariamente no código de leitura.
Está na arquitetura de armazenamento.
Em produção, geralmente utilizamos fontes acessíveis aos componentes relevantes do cluster, como:
HDFS
S3
ADLS
GCS
Distributed Storage
ou volumes compartilhados adequadamente configurados.
Essa é uma das diferenças mais importantes entre desenvolvimento local e execução distribuída.
27. Código local não é necessariamente código distribuído
Considere:
with open(
"/home/usuario/config.json"
) as arquivo:
configuracao = arquivo.read()
Se isso acontecer no Driver, o arquivo precisa estar acessível ao Driver.
Agora imagine que uma função executada pelos workers tente abrir esse mesmo caminho.
Os Executors podem estar em máquinas ou containers diferentes.
Então precisamos perguntar:
Onde o arquivo existe?
E:
Qual processo precisa acessá-lo?
Esse raciocínio se conecta à Parte 9 sobre closures, serialização e variáveis distribuídas.
28. Empacotamento da aplicação
Em projetos reais, uma aplicação Spark raramente é apenas um arquivo.
Podemos ter:
spark-project/
|
+-- app.py
+-- src/
| +-- transformations/
| +-- validations/
| +-- connectors/
|
+-- config/
+-- tests/
+-- requirements.txt
Em produção, precisamos garantir que o código e suas dependências estejam disponíveis onde serão executados.
Isso pode envolver:
- Pacotes Python.
- Arquivos distribuídos.
- Imagens de container.
- Bibliotecas JVM.
- Dependências nativas.
- Configuração de ambiente.
Uma aplicação que funciona localmente pode falhar em produção simplesmente porque uma dependência não foi disponibilizada aos Executors.
29. Python e ambiente de execução
Em PySpark, precisamos lembrar que existe execução de código Python associada aos workers.
Isso significa que versões e dependências Python importam.
Por exemplo:
Driver
|
+-- Python Environment
|
Executors
|
+-- Python Workers
|
+-- Required Libraries
Se uma biblioteca existe apenas na máquina cliente, mas não está disponível no ambiente dos workers, determinadas operações podem falhar.
Em ambientes containerizados, uma estratégia comum é construir imagens que contenham as dependências necessárias.
Em outras plataformas, podemos distribuir ambientes ou pacotes conforme os mecanismos suportados.
30. Logs: onde procurar?
Agora chegamos a uma questão prática.
Quando uma aplicação falha, onde estão os logs?
A resposta depende do ambiente.
Client Mode
Os logs do Driver normalmente estão associados ao processo de submissão.
Os logs dos Executors ficam no ambiente onde eles executam.
Cluster Mode
Os logs do Driver normalmente precisam ser consultados por meio dos mecanismos da plataforma.
Em Kubernetes, por exemplo, podemos investigar os logs do Driver Pod.
Em YARN, podemos utilizar os mecanismos de logs da aplicação.
O ponto principal é:
Saber onde o Driver executa ajuda a saber onde procurar o erro.
31. Spark UI
A Spark UI continua sendo uma das ferramentas mais importantes de observabilidade.
Ela permite investigar informações como:
Jobs
Stages
Tasks
Executors
Storage
SQL Queries
Dependendo do ambiente e da configuração, podemos acessar a interface diretamente ou por meio de proxies, túneis e interfaces da plataforma.
A Spark UI normalmente utiliza a porta 4040 como ponto inicial para aplicações em execução, mas a porta pode variar quando já está ocupada ou quando a plataforma utiliza mecanismos próprios.
Não devemos assumir que a interface estará diretamente exposta na rede.
32. Spark History Server
Existe uma diferença importante entre observar uma aplicação em execução e investigar uma aplicação que já terminou.
Durante a execução, a Spark UI oferece informações do estado atual.
Para análise posterior, podemos utilizar o Spark History Server, quando o registro de eventos está habilitado e configurado.
Conceitualmente:
Spark Application
|
v
Event Logs
|
v
Persistent Storage
|
v
Spark History Server
|
v
Post-execution Analysis
Isso é especialmente útil em ambientes de produção.
Imagine um pipeline que executa às 3h da manhã.
Se ele falhar, precisamos conseguir investigar o que aconteceu depois.
33. Falha de Executor vs. falha de Driver
Vamos conectar com a Parte 8.
Executor Failure
Executor 2
|
v
Failure
|
v
Lost Tasks / Data
|
v
Retry / Recomputation
Em determinados cenários, Spark consegue recuperar o trabalho.
Driver Failure
Driver
|
v
Failure
|
v
Application Coordination Lost
A falha do Driver possui consequências diferentes.
O reinício ou a recuperação da aplicação depende dos mecanismos de implantação, supervisão e tolerância a falhas disponíveis.
Por isso, escolher Client Mode ou Cluster Mode também influencia a estratégia operacional.
34. Cluster Mode não significa alta disponibilidade automática
Esse é um ponto importante.
Executar o Driver dentro do cluster não garante, por si só, que ele seja automaticamente recuperado de qualquer falha.
Podemos ter:
Cluster Mode
|
v
Driver Pod
|
v
Failure
A recuperação depende de mecanismos como:
- Supervisão da aplicação.
- Políticas de reinício.
- Recursos do Cluster Manager.
- Orquestração externa.
- Persistência de estado.
- Reexecução do Job.
Portanto:
Cluster Mode
não é sinônimo de:
Exactly-once execution
nem de:
Automatic complete recovery
Essas garantias precisam ser analisadas separadamente.
35. Orquestração de Jobs Spark
Em ambientes reais, aplicações Spark frequentemente fazem parte de pipelines maiores.
Por exemplo:
Airflow / Orchestrator
|
v
spark-submit
|
v
Spark Application
|
v
Data Lake
|
v
Validation
|
v
Analytics
O orquestrador controla aspectos como:
- Agendamento.
- Dependências entre Jobs.
- Retentativas.
- Alertas.
- Parâmetros.
- Monitoramento do workflow.
O Spark executa o processamento distribuído.
São responsabilidades complementares.
36. Uma arquitetura de produção
Imagine uma plataforma de Engenharia de Dados:
ORCHESTRATOR
|
v
SPARK JOB
|
v
CLUSTER MANAGER
|
+--------+--------+
| | |
v v v
DRIVER EXECUTOR EXECUTOR
| | |
+--------+--------+
|
v
DATA LAKE
|
v
DATA QUALITY
|
v
ANALYTICS
Na prática, o Driver coordena os Executors, e o Cluster Manager administra os recursos necessários à aplicação.
Esse tipo de arquitetura exige decisões sobre:
- Deployment Mode.
- Recursos.
- Armazenamento.
- Dependências.
- Logs.
- Segurança.
- Observabilidade.
- Recuperação.
- Custos.
Não basta que o código funcione.
Precisamos que ele seja operável.
37. Um checklist antes de implantar
Antes de enviar uma aplicação Spark para produção, gosto de responder:
- Qual Cluster Manager será utilizado?
- O Driver executará em Client ou Cluster Mode?
- Onde os Executors serão iniciados?
- Driver e Executors conseguem se comunicar?
- Os dados estão acessíveis ao cluster?
- As dependências Python estão disponíveis?
- As credenciais estão configuradas com segurança?
- Qual é a política de recursos?
- Onde ficam os logs do Driver?
- Onde ficam os logs dos Executors?
- Os event logs estão habilitados?
- Como a aplicação será monitorada?
- Como falhas serão tratadas?
- O Job pode ser reexecutado com segurança?
- Como serão controlados custos e consumo de recursos?
Essas perguntas transformam uma aplicação experimental em uma aplicação operacionalmente preparada.
38. Problemas comuns de implantação
Alguns erros aparecem repetidamente.
A aplicação funciona localmente, mas falha no cluster.
Possíveis causas:
- Dependências ausentes.
- Arquivos locais indisponíveis.
- Credenciais incorretas.
- Diferenças de versão.
- Configuração de rede.
Executors não conseguem se conectar ao Driver.
Possíveis causas:
- Firewall.
- DNS.
- Endereço anunciado incorretamente.
- Portas.
- Configuração de rede.
A aplicação é encerrada após fechar a sessão cliente.
Verifique se o Driver está executando em Client Mode e como o processo é supervisionado.
O Job termina, mas não conseguimos investigar sua execução.
Verifique event logs, retenção e configuração do History Server.
O Driver funciona, mas Tasks falham com erro de biblioteca.
Verifique as dependências nos ambientes dos workers.
Esses problemas não são necessariamente erros de lógica de transformação.
Muitas vezes são erros de implantação.
39. O que muda em plataformas gerenciadas?
Em plataformas gerenciadas de Spark, muitos detalhes de infraestrutura são abstraídos.
Podemos encontrar interfaces para:
- Criar clusters.
- Definir Jobs.
- Configurar recursos.
- Consultar logs.
- Executar notebooks.
- Agendar pipelines.
- Gerenciar dependências.
Isso simplifica a operação.
Mas não elimina os fundamentos.
Continuamos tendo:
Driver
Executors
Tasks
Partitions
Shuffle
Memory
A plataforma pode esconder parte da complexidade operacional.
Ela não elimina a física do processamento distribuído.
40. A relação com custos
Agora imagine duas aplicações.
Aplicação A
Driver
|
v
4 Executors
|
v
Job completes in 10 minutes
Aplicação B
Driver
|
v
20 Executors
|
v
Job completes in 9 minutes
A aplicação B utiliza muito mais recursos para economizar apenas um minuto.
Dependendo do modelo de cobrança, isso pode ser economicamente pior.
Mais Executors não significam automaticamente melhor eficiência.
Precisamos avaliar:
Execution Time
+
Resource Consumption
+
Infrastructure Cost
+
Operational Requirements
Esse raciocínio conecta performance tuning e FinOps.
41. O modelo mental completo
Agora podemos conectar os dez primeiros capítulos.
SPARK APPLICATION
|
v
SUBMISSION
|
v
DEPLOYMENT MODE
|
+----------+----------+
| |
v v
CLIENT CLUSTER
| |
+----------+----------+
|
v
DRIVER
|
v
SPARK PLAN
|
v
JOBS
|
v
STAGES
|
v
TASKS
|
v
EXECUTORS
|
+----------+----------+
| | |
v v v
MEMORY SHUFFLE CPU
| | |
+----------+----------+
|
v
RESULT
Essa visão mostra que a arquitetura do Spark possui duas dimensões complementares.
A dimensão de implantação:
Where does it run?
A dimensão de execução:
How does it process data?
Para trabalhar com Spark em produção, precisamos compreender as duas.
42. A principal lição deste capítulo
Se eu tivesse que resumir Client Mode vs. Cluster Mode em uma única ideia, seria:
O Deployment Mode define onde o Driver executa; o Cluster Manager administra os recursos; e o Spark continua responsável por coordenar o processamento distribuído.
Parece uma distinção simples.
Mas ela influencia:
- Arquitetura.
- Rede.
- Disponibilidade.
- Observabilidade.
- Troubleshooting.
- Segurança.
- Operação.
- Custos.
Quando sabemos onde cada componente executa, muitos erros deixam de parecer misteriosos.
43. Como penso hoje
Quando recebo um problema como:
A aplicação Spark funciona no notebook, mas falha em produção.
Não começo necessariamente pelo DataFrame.
Primeiro quero entender:
Qual é o ambiente?
|
v
Qual é o Cluster Manager?
|
v
Client ou Cluster Mode?
|
v
Onde está o Driver?
|
v
Onde estão os Executors?
|
v
Os dados são acessíveis?
|
v
As dependências estão disponíveis?
|
v
Existe conectividade?
|
v
Onde estão os logs?
|
v
Qual componente falhou?
Só depois avanço para o plano físico, memória, shuffle e operações distribuídas, quando esses forem os pontos relevantes.
Essa abordagem reduz o tempo de diagnóstico e evita alterar configurações que não têm relação com a causa real.
Próximo artigo
Agora sabemos como uma aplicação Spark é submetida e onde seus componentes executam.
Mas existe outro desafio importante:
Como configurar corretamente os recursos de uma aplicação Spark?
No próximo capítulo vamos aprofundar:
-
spark.executor.instances. -
spark.executor.cores. -
spark.executor.memory. -
spark.driver.memory. - Dynamic Allocation.
- Paralelismo.
- Número de partições.
- Resource sizing.
- Relação entre CPU, memória e shuffle.
- Dimensionamento para workloads batch.
- Trade-offs entre desempenho e custo.
- Estratégias de benchmarking.
- Como evitar configurações copiadas sem diagnóstico.
Vamos conectar:
Workload
|
v
Data Volume
|
v
Partitions
|
v
Parallelism
|
v
Executor Resources
|
v
Execution Time
|
v
Infrastructure Cost
Porque configurar recursos não é apenas escolher números.
É compreender como a aplicação utiliza o cluster.
Série: Como aprendi Apache Spark
← Parte 9: Broadcast, Accumulators e Closures
Próximo: Parte 11 — Dimensionamento e configuração de recursos no Apache Spark
Top comments (0)