DEV Community

renanpyd
renanpyd

Posted on

Como aprendi Apache Spark — Parte 10: Client Mode vs. Cluster Mode — onde o Spark realmente executa

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()
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

É 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
Enter fullscreen mode Exit fullscreen mode

e:

Cluster Mode
Enter fullscreen mode Exit fullscreen 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

não substitui:

Spark DAG Scheduler
Enter fullscreen mode Exit fullscreen mode

nem:

Spark Task Scheduler
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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()
)
Enter fullscreen mode Exit fullscreen mode

O parâmetro:

local[*]
Enter fullscreen mode Exit fullscreen mode

indica que o Spark pode utilizar os núcleos lógicos disponíveis na máquina local.

Também podemos utilizar:

local[2]
Enter fullscreen mode Exit fullscreen mode

para configurar dois threads de execução local.

Exemplo:

spark = (
    SparkSession.builder
    .master("local[2]")
    .appName("SparkLocal")
    .getOrCreate()
)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Os valores exatos dependem do ambiente.


20. Exemplo local com spark-submit

Vamos criar uma aplicação simples.

Arquivo:

app.py
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

Executamos:

spark-submit \
  --master "local[*]" \
  app.py
Enter fullscreen mode Exit fullscreen mode

Resultado esperado:

Quantidade de números pares: 500000
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Os valores são placeholders e precisam ser substituídos pelos recursos reais do ambiente.

Observe:

k8s://
Enter fullscreen mode Exit fullscreen mode

que identifica a integração com Kubernetes.

E:

local:///opt/spark/app.py
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

--deploy-mode

Indica a localização do Driver.

Exemplos:

client
cluster
Enter fullscreen mode Exit fullscreen mode

Portanto:

--master yarn \
--deploy-mode cluster
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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?
Enter fullscreen mode Exit fullscreen mode

E:

Qual processo precisa acessá-lo?
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Em determinados cenários, Spark consegue recuperar o trabalho.

Driver Failure

Driver
   |
   v
Failure
   |
   v
Application Coordination Lost
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

não é sinônimo de:

Exactly-once execution
Enter fullscreen mode Exit fullscreen mode

nem de:

Automatic complete recovery
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

  1. Qual Cluster Manager será utilizado?
  2. O Driver executará em Client ou Cluster Mode?
  3. Onde os Executors serão iniciados?
  4. Driver e Executors conseguem se comunicar?
  5. Os dados estão acessíveis ao cluster?
  6. As dependências Python estão disponíveis?
  7. As credenciais estão configuradas com segurança?
  8. Qual é a política de recursos?
  9. Onde ficam os logs do Driver?
  10. Onde ficam os logs dos Executors?
  11. Os event logs estão habilitados?
  12. Como a aplicação será monitorada?
  13. Como falhas serão tratadas?
  14. O Job pode ser reexecutado com segurança?
  15. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Aplicação B

Driver
  |
  v
20 Executors
  |
  v
Job completes in 9 minutes
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Essa visão mostra que a arquitetura do Spark possui duas dimensões complementares.

A dimensão de implantação:

Where does it run?
Enter fullscreen mode Exit fullscreen mode

A dimensão de execução:

How does it process data?
Enter fullscreen mode Exit fullscreen mode

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?
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)