Risoluzione dei problemi di Spark

Questo articolo descrive i problemi principali che possono verificarsi quando si usano i payload di Spark in Apache Ambari unitamente alle risoluzioni.

Procedura per configurare un'applicazione Spark tramite Ambari nei cluster

Problema:

Necessità di configurare in Ambari la quantità di memoria e il numero di core che un'applicazione Spark può usare.

Procedura per la risoluzione:

I valori di configurazione indicati in questa procedura devono essere già stati impostati nei cluster HDInsight Spark. Fare riferimento a Why did my Spark application fail with an OutOfMemoryError? (Perché l'applicazione Spark è terminata con un'eccezione OutOfMemoryError?) per determinare quali configurazioni Spark è necessario impostare e su quali valori.

  1. Scegliere Spark2 dall'elenco dei cluster.

    Selezionare un cluster dall'elenco

  2. Fare clic sulla scheda Configurazioni .

    Scegliere la scheda Configurazioni

  3. Nell'elenco delle configurazioni scegliere Custom-spark2-defaults.

    Scegliere custom-spark-defaults

  4. Ricercare l'impostazione del valore che si desidera modificare, come spark.executor.memory. In questo caso, il valore 4608m è troppo alto.

    Selezionare il campo spark.executor.memory

  5. Impostare il valore consigliato. In questo caso, il valore consigliato per questa impostazione è 2048.

    Cambiare il valore in 2048m

  6. Salvare il valore dell'impostazione, quindi salvare la configurazione.

    Fare clic su Save sulla barra degli strumenti.

    Salvare l'impostazione e la configurazione

    Si riceve una notifica se una delle configurazioni richiede attenzione. Prendere nota delle configurazioni, quindi fare clic su Proceed Anyway (Continuare comunque).

    Fare clic su Proceed Anyway (Continuare comunque)

    Immettere una nota sulle modifiche apportate alla configurazione, quindi fare clic su Salva.

    Immettere una nota sulle modifiche apportate

  7. Ogni volta che viene salvata una configurazione, viene chiesto di riavviare il servizio. Fare clic su Restart.

    Fare clic su Restart

    Confermare il riavvio.

    Fare clic su Confirm Restart All (Conferma riavvio completo)

    È possibile esaminare i processi in esecuzione.

    Esaminare i processi in esecuzione

  8. È possibile anche aggiungere configurazioni. Nell'elenco delle configurazioni selezionare Custom-spark2-defaults, come nel passaggio 3, quindi scegliere Aggiungi proprietà.

    Fare clic su Aggiungi proprietà

  9. Definire una nuova proprietà. È possibile definire una singola proprietà usando una finestra di dialogo per configurare impostazioni specifiche, come il tipo di dati, oppure definire più proprietà con una definizione per riga.

    In questo esempio la proprietà spark.driver.memory è stata definita con un valore di 4g.

    Definire una nuova proprietà

  10. Salvare la configurazione e riavviare il servizio come descritto nei passaggi 6 e 7.

Queste modifiche si applicano a tutto il cluster ma possono essere ignorate al momento effettivo dell'invio del processo Spark.

Altre informazioni:

Invio del processo Spark nei cluster HDInsight

Procedura per configurare un'applicazione Spark tramite il notebook di Jupyter nei cluster

Problema:

Necessità di configurare la quantità di memoria e il numero di core che possono essere usati da un'applicazione Spark quando si usa il notebook Jupyter nei cluster HDInsight.

  1. Fare riferimento all'argomento Why did my Spark application fail with OutOfMemoryError? (Perché l'applicazione Spark è terminata con un'eccezione OutOfMemoryError?) per determinare quali configurazioni Spark devono essere impostate e su quali valori.
  2. Specificare le configurazioni Spark in un formato JSON valido nella prima cella del notebook di Jupyter dopo la direttiva %%configure (modificare il valore effettivo secondo necessità):

Aggiungere una configurazione

Altre informazioni:

Invio del processo Spark nei cluster HDInsight

Procedura per configurare un'applicazione Spark nei cluster tramite LIVY

Problema:

Necessità di configurare, al momento dell'invio tramite LIVY, la quantità di memoria e il numero di core che un'applicazione Spark può usare nei cluster HDInsight.

  1. Fare riferimento all'argomento Why did my Spark application fail with OutOfMemoryError? (Perché l'applicazione Spark è terminata con un'eccezione OutOfMemoryError?) per determinare quali configurazioni Spark devono essere impostate e su quali valori.
  2. Inviare l'applicazione Spark a LIVY usando un client REST, come CURL, con un comando simile al seguente (modificare i valori effettivi secondo necessità):
curl -k --user 'username:password' -v -H 'Content-Type: application/json' -X POST -d '{ "file":"wasb://container@storageaccountname.blob.core.windows.net/example/jars/sparkapplication.jar", "className":"com.microsoft.spark.application", "numExecutors":4, "executorMemory":"4g", "executorCores":2, "driverMemory":"8g", "driverCores":4}'  

Altre informazioni:

Invio del processo Spark nei cluster HDInsight

Procedura per configurare un'applicazione Spark tramite un script spark-submit nei cluster

Problema:

Necessità di configurare, al momento dell'invio tramite uno script spark-submit, la quantità di memoria e il numero di core che un'applicazione Spark può usare nei cluster HDInsight.

  1. Fare riferimento all'argomento Why did my Spark application fail with OutOfMemoryError? (Perché l'applicazione Spark è terminata con un'eccezione OutOfMemoryError?) per determinare quali configurazioni Spark devono essere impostate e su quali valori.
  2. Avviare spark-shell usando un comando simile al seguente (modificare il valore effettivo delle configurazioni secondo necessità):
spark-submit --master yarn-cluster --class com.microsoft.spark.application --num-executors 4 --executor-memory 4g --executor-cores 2 --driver-memory 8g --driver-cores 4 /home/user/spark/sparkapplication.jar

Altre informazioni:

Invio del processo Spark nei cluster HDInsight

Causa dell'eccezione OutOfMemoryError in un'applicazione Spark

Error:

Spark application failed with OutOfMemoryError exception (Applicazione Spark terminata con un'eccezione OutOfMemoryError).

Descrizione dettagliata:

L'applicazione Spark termina con un errore quando si verificano i seguenti tipi di eccezioni non rilevate.

ERROR Executor: Exception in task 7.0 in stage 6.0 (TID 439) 

java.lang.OutOfMemoryError 
    at java.io.ByteArrayOutputStream.hugeCapacity(Unknown Source) 
    at java.io.ByteArrayOutputStream.grow(Unknown Source) 
    at java.io.ByteArrayOutputStream.ensureCapacity(Unknown Source) 
    at java.io.ByteArrayOutputStream.write(Unknown Source) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(Unknown Source) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(Unknown Source) 
    at java.io.ObjectOutputStream.writeObject0(Unknown Source) 
    at java.io.ObjectOutputStream.writeObject(Unknown Source) 
    at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:44) 
    at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:101) 
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:239) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 
ERROR SparkUncaughtExceptionHandler: Uncaught exception in thread Thread[Executor task launch worker-0,5,main] 

java.lang.OutOfMemoryError 
    at java.io.ByteArrayOutputStream.hugeCapacity(Unknown Source) 
    at java.io.ByteArrayOutputStream.grow(Unknown Source) 
    at java.io.ByteArrayOutputStream.ensureCapacity(Unknown Source) 
    at java.io.ByteArrayOutputStream.write(Unknown Source) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(Unknown Source) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(Unknown Source) 
    at java.io.ObjectOutputStream.writeObject0(Unknown Source) 
    at java.io.ObjectOutputStream.writeObject(Unknown Source) 
    at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:44) 
    at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:101) 
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:239) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 

Possibile causa:

Questa eccezione è probabilmente dovuta a una quantità insufficiente di memoria heap allocata per le Java Virtual Machine (JVM) che vengono avviate come executor o driver dell'applicazione Spark.

Procedura per la risoluzione:

  1. Determinare le dimensioni massime dei dati che possono essere gestiti dall'applicazione Spark. Un'ipotesi può basarsi sulle dimensioni massime dei dati di input, i dati intermedi prodotti trasformando i dati di input e i dati di output ottenuti dalla trasformazione ulteriore dei dati intermedi. Può trattarsi di un processo iterativo anche se l'ipotesi iniziale non è possibile.
  2. Assicurarsi che il cluster HDInsight da utilizzare disponga di sufficienti risorse in termini di memoria e core per supportare l'applicazione Spark. Ciò può essere determinato visualizzando la sezione Cluster Metrics (Metriche cluster) dell'interfaccia utente YARN del cluster e confrontando i valori di Memory Used (memoria usata) e Memory Total (memoria totale), VCores Used (VCore utilizzati) e VCores Total (VCore totali).

  3. Impostare le seguenti configurazioni Spark su valori appropriati che non superino il 90% della memoria e dei core disponibili, visualizzati da YARN, verificando che siano compresi entro i requisiti di memoria di Spark:

spark.executor.instances (Example: 8 for 8 executor count) 
spark.executor.memory (Example: 4g for 4 GB) 
spark.yarn.executor.memoryOverhead (Example: 384m for 384 MB) 
spark.executor.cores (Example: 2 for 2 cores per executor) 
spark.driver.memory (Example: 8g for 8GB) 
spark.driver.cores (Example: 4 for 4 cores)   
spark.yarn.driver.memoryOverhead (Example: 384m for 384MB) 

Memoria totale usata da tutti gli esecutori =

spark.executor.instances * (spark.executor.memory + spark.yarn.executor.memoryOverhead) 

Memoria totale usata dal driver =

spark.driver.memory + spark.yarn.driver.memoryOverhead

Altre informazioni: