Infra

Nível médio

Memória do driver vs. memória do executor: não são o mesmo problema de ajuste

«Só aumenta a memória» funciona diferente dependendo de qual memória - e aumentar a errada só adia o mesmo crash.

Ler em:
collect() / toPandas() Broadcast superdimensionado Muitas partições rastreadas
As fontes usuais de pressão de memória no driver, aproximadamente em ordem - ilustrativo, não medido.

O driver roda um trabalho fundamentalmente diferente do de um executor: ele constrói e planeja o DAG, não processa partições de dados - o que significa que a pressão de memória dele vem de lugares completamente diferentes.

O que realmente roda no driver

Construção do plano e planejamento do DAG, coordenação da atribuição de tarefas aos executors, coleta de valores de acumuladores, e qualquer coisa que traga dados de volta explicitamente para o processo do driver - collect(), toPandas(), take() num resultado grande. Nada disso é «processar partições do seu dataset», que é inteiramente trabalho dos executors.

Por que o OOM do driver tem causas reais diferentes

A mais comum, de longe: alguém chamou .collect() ou .toPandas() num DataFrame muito maior do que o esperado, trazendo tudo para o processo único do driver em vez de manter distribuído. A segunda mais comum: um broadcast join (veja o artigo sobre broadcast join) onde o lado «pequeno» na verdade não era - o driver coleta esses dados antes de enviá-los aos executors, então é o primeiro a dar OOM. A terceira: um job rastreando um número enorme de partições ou um DAG muito profundo, onde só o overhead de agendamento - sem nenhum dado real envolvido - consome o heap do driver.

Por que aumentar a memória do executor não resolve nada disso

spark.executor.memory e spark.driver.memory são configurações genuinamente separadas controlando processos JVM separados - aumentar uma não faz nada pela pressão na outra. Um OOM do driver por um collect() inesperado precisa de um ajuste de código (agregar antes de coletar, ou simplesmente não coletar) ou de spark.driver.memory especificamente; dar mais memória ao executor nesse caso está mexendo num processo que nunca foi o que estava ficando sem memória.

Diagnóstico rápido: um OOM de executor aparece como uma tarefa específica falhando com um ExecutorLostFailure ou parecido no event log. Um OOM do driver mata a aplicação inteira de uma vez, muitas vezes sem uma única tarefa falha para apontar - uma forma completamente diferente, e a primeira pista de que você está olhando para o ajuste errado.

Veja como isso fica no seu próprio pipeline.

Envie um event log real do Spark, um run_results.json do dbt, ou uma exportação de métricas do Flink, e receba recomendações concretas que exigem sua aprovação - não mais uma regra geral.