Resolução
A causa raiz e a solução apropriada para esse erro dependem do seu workload. Para solucionar o erro, use os seguintes métodos de solução de problemas, na seguinte ordem.
Aumente a sobrecarga de memória
Sobrecarga de memória é a quantidade de memória off-heap alocada a cada executor. Por padrão, o Spark define a sobrecarga de memória como 10% da memória do executor, ou 384, o que for maior. Buffers diretos Java NIO, pilhas de threads, bibliotecas nativas compartilhadas e arquivos mapeados em memória usam essa sobrecarga de memória.
Faça aumentos graduais na sobrecarga de memória, até 25%. A soma da memória do driver ou do executor mais a sobrecarga de memória deve ser menor que yarn.nodemanager.resource.memory-mb para seu tipo de instância:
"spark.driver/executor.memory + spark.driver/executor.memoryOverhead < yarn.nodemanager.resource.memory-mb"
Se o erro ocorrer no contêiner do driver ou no contêiner do executor, aumente a sobrecarga de memória somente para o contêiner em que o erro ocorreu. É possível aumentar a sobrecarga de memória em um cluster em execução, em um novo cluster ou ao enviar um trabalho.
Cluster em execução
Modifique spark-defaults.conf no nó primário.
Por exemplo:
sudo vim /etc/spark/conf/spark-defaults.conf
spark.driver.memoryOverhead 512
spark.executor.memoryOverhead 512
Novo cluster
Ao executar um cluster, adicione um objeto de configuração semelhante ao exemplo a seguir:
[
{
"Classification": "spark-defaults",
"Properties": {
"spark.driver.memoryOverhead": "512",
"spark.executor.memoryOverhead": "512"
}
}
]
Trabalho único
Para aumentar a sobrecarga de memória ao executar spark-submit, use a opção --conf.
Exemplo:
spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --conf spark.driver.memoryOverhead=512 --conf spark.executor.memoryOverhead=512 /usr/lib/spark/examples/jars/spark-examples.jar 100
Se você continuar recebendo o erro depois de aumentar a sobrecarga de memória, reduza o número de núcleos do executor.
Reduza o número de núcleos do executor
Observação: reverta todas as alterações feitas em spark-defaults.conf na seção anterior.
Ao reduzir o número de núcleos do executor, você reduz o número máximo de tarefas que o executor pode realizar, o que reduz a quantidade de memória necessária. Dependendo do contêiner do driver que gera o erro ou do outro contêiner do executor que recebe o erro, diminua o número de núcleos do driver ou do executor.
Cluster em execução
Modifique spark-defaults.conf no nó primário.
Exemplo:
sudo vim /etc/spark/conf/spark-defaults.confspark.driver.cores 3
spark.executor.cores 3
Novo cluster
Ao executar um cluster, adicione um objeto de configuração semelhante ao exemplo a seguir:
[
{
"Classification": "spark-defaults",
"Properties": {"spark.driver.cores" : "3",
"spark.executor.cores": "3"
}
}
]
Trabalho único
Para reduzir o número de núcleos do executor ao executar spark-submit, use a —executor-cores.
Exemplo:
spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --executor-cores 3 --driver-cores 3 /usr/lib/spark/examples/jars/spark-examples.jar 100
Se você continuar recebendo a mensagem de erro, aumente o número de partições.
Aumente o número de partições
Observação: reverta todas as alterações feitas em spark-defaults.conf na seção anterior.
Para aumentar o número de partições, aumente o valor de spark.default.parallelism em conjuntos de dados distribuídos resilientes brutos ou execute uma operação .repartition().
Ao aumentar o número de partições, você reduz a quantidade de memória necessária por partição. O Spark usa muito a RAM do cluster como uma forma eficaz de maximizar a velocidade. Portanto, você deve monitorar o uso da memória com Ganglia (no Amazon EMR versão 6.15) ou o agente Amazon CloudWatch (no Amazon EMR 7.0 e versões posteriores). Em seguida, verifique se as configurações do seu cluster e a estratégia de particionamento atendem às crescentes necessidades de dados. Se você continuar a receber a mensagem de erro "Container killed by YARN for exceeding memory limits", aumente a memória do driver e do executor.
Aumente a memória do driver e do executor
Observação: reverta todas as alterações feitas em spark-defaults.conf na seção anterior.
Se o erro ocorrer em um contêiner de driver ou em um contêiner de executor, aumente a memória do driver ou do executor, mas não de ambos. Certifique-se de que a soma da memória do driver ou do executor mais a sobrecarga de memória do driver ou do executor seja sempre menor que o valor de yarn.nodemanager.resource.memory-mb para seu tipo de instância do EC2:
"spark.driver/executor.memory + spark.driver/executor.memoryOverhead < yarn.nodemanager.resource.memory-mb"
Cluster em execução
Modifique spark-defaults.conf no nó primário.
Exemplo:
sudo vim /etc/spark/conf/spark-defaults.conf
spark.executor.memory 1g
spark.driver.memory 1g
Novo cluster
Adicione um objeto de configuração semelhante ao seguinte ao executar um cluster:
[
{
"Classification": "spark-defaults",
"Properties": {
"spark.executor.memory": "1g",
"spark.driver.memory":"1g",
}
}
]
Trabalho único
Use as opções --executor-memory e --driver-memory para aumentar a memória ao executar spark-submit.
Exemplo:
spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --executor-memory 1g --driver-memory 1g /usr/lib/spark/examples/jars/spark-examples.jar 100
Outras etapas de solução de problemas:
Se você continuar a receber a mensagem de erro, realize as seguintes ações:
- Execute sua aplicação em um conjunto de dados de amostra. O benchmarking é uma prática recomendada e pode ajudá-lo a identificar lentidões e partições distorcidas que causam problemas de memória.
- Processe a quantidade mínima de dados necessários. Se você não filtrar seus dados ou se filtrar no final da execução da aplicação, o excesso de dados poderá tornar a aplicação mais lenta. Isso pode aumentar a chance de uma exceção de memória.
- Particione seus dados para ingerir somente os dados necessários.
- Use uma estratégia de particionamento diferente. Por exemplo, particione em uma chave alternativa para evitar partições grandes e distorcidas.
- Sua instância do EC2 pode não ter os recursos de memória necessários para seu workload. Mude para um tipo de instância maior com otimização de memória. Se você continuar a ter exceções de memória depois de alterar os tipos de instância, experimente os métodos de solução de problemas na nova instância.
Informações relacionadas
Spark configuration (Configuração do Spark) no site do Apache Spark
Como resolvo o erro "java.lang.ClassNotFoundException" error in Spark on Amazon EMR?