Problemas de memória do Spark
Quando os executores ficam sem memória, o Spark os remove e repete suas tarefas. O job diminui a velocidade e, após falhas repetidas, o estágio e o job falham.
Use esta página quando os jobs falharem ou os executores forem removidos e o log de eventos do compute não mostrar perdas de instância spot ou preemptiva ou autoscale. Para verificar o log de eventos, consulte Falha em jobs ou executores removidos. Se o stage for concluído, mas for lento e mostrar spill, consulte Skew and spill.
Verificando um problema de memória
Problemas de memória geralmente causam erros como:
SparkException: Job aborted due to stage failure: Task 3 in stage 0.0 failed 4 times, most recent failure: Lost task 3.3 in stage 0.0 (TID 30) (10.139.64.114 executor 4): ExecutorLostFailure (executor 4 exited caused by one of the running tasks) Reason: Remote RPC client disassociated. Likely due to containers exceeding thresholds, or network issues. Check driver logs for WARN messages.
Esses erros são frequentemente genéricos e outros problemas podem causar isso. Se você suspeitar de um problema de memória, verifique dobrando a memória por núcleo para ver se isso resolve o problema.
Por exemplo, se o tipo de worker tiver 4 núcleos e 16 GB de memória, mude para um tipo de worker com 4 núcleos e 32 GB de memória. Isso lhe dá 8 GB por núcleo em vez de 4 GB. A proporção de memória para núcleos é importante, não o total de memória. Se o job demora mais para falhar ou não falha, a memória pode ser a causa.
Se mais memória corrigir o problema, mantenha o tipo de worker maior. Se não for, ou se o custo adicional for muito alto, verifique as possíveis causas na próxima seção.
Causas possíveis
Problemas de memória têm muitas causas possíveis. Comece por estas causas comuns:
- Poucas partições de embaralhamento. Defina
spark.sql.shuffle.partitionscomoautopara que o Spark escolha o número de partições de embaralhamento. Consulte configuração do AQE. - Uma grande transmissão. Verifique se há dicas de join de transmissão em grandes tabelas e revise o limite de transmissão do Runtime. Consulte Configuração de AQE.
- UDFs. Cada tarefa que executa um UDF pode carregar todos os dados de sua partição na memória. Reescreva o UDF usando funções nativas ou faça o repartition antes de aplicá-lo. Consulte UDFs lentas.
- Uma função de janela sem
PARTITION BY. Adicione uma cláusulaPARTITION BYpara que a janela não abranja todo o dataset. Veja Estágio longo do Spark com uma tarefa. - Inclinação. Verifique a inclinação nas Métricas de resumo do estágio. Veja Inclinação. Para joins, veja Tratar dinamicamente join de inclinação.
- Estado de transmissão. Para queries que mantêm estado de transmissão, use o armazenamento do estado RocksDB e limite seu uso de memória. Veja Limitar o uso de memória do RocksDB.