2015-06-08 11 views
15

Sto cercando di ottimizzare l'utilizzo del cluster per un'attività semplice.Risorse spark non allocate completamente su Amazon EMR

Cluster è 1 + 2 x m3.xlarge, runnning Spark 1.3.1, Hadoop 2.4, Amazon AMI 3,7

Il compito legge tutte le righe di un file di testo e li analizza come csv.

Quando ho scintille invio un compito come una modalità di filo-cluster, ottengo uno dei seguenti risultati:

  • 0 esecutore: lavoro attende all'infinito fino a quando ho ucciso manualmente
  • 1 esecutore: lavoro sotto utilizzare le risorse con solo 1 macchina per la lavorazione
  • OOM quando non si assegna abbastanza memoria dal driver

Quello che mi sarei aspettato:

  • Il driver Spark viene eseguito su cluster master con tutta la memoria disponibile, più 2 executors con 9404 MB ciascuno (come definito da script install-spark).

A volte, quando ottengo un'esecuzione "riuscita" con 1 executor, la clonazione e il riavvio del passo termina con 0 executor.

Ho creato cluster utilizzando questo comando:

aws emr --region us-east-1 create-cluster --name "Spark Test" 
--ec2-attributes KeyName=mykey 
--ami-version 3.7.0 
--use-default-roles 
--instance-type m3.xlarge 
--instance-count 3 
--log-uri s3://mybucket/logs/ 
--bootstrap-actions Path=s3://support.elasticmapreduce/spark/install-spark,Args=["-x"] 
--steps Name=Sample,Jar=s3://elasticmapreduce/libs/script-runner/script-runner.jar,Args=[/home/hadoop/spark/bin/spark-submit,--master,yarn,--deploy-mode,cluster,--class,my.sample.spark.Sample,s3://mybucket/test/sample_2.10-1.0.0-SNAPSHOT-shaded.jar,s3://mybucket/data/],ActionOnFailure=CONTINUE 

Con alcune varianti passo tra cui:

--driver memoria 8G --driver-core 4 --num-esecutori 2


install-scintilla script con -x produce il seguente scintilla defaults.conf:

$ cat spark-defaults.conf 
spark.eventLog.enabled false 
spark.executor.extraJavaOptions   -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:MaxHeapFreeRatio=70 
spark.driver.extraJavaOptions   -Dspark.driver.log.level=INFO 
spark.executor.instances  2 
spark.executor.cores 4 
spark.executor.memory 9404M 
spark.default.parallelism  8 

Update 1

ottengo lo stesso comportamento con un esempio generico JavaWordCount:

/home/hadoop/spark/bin/spark-submit --verbose --master yarn --deploy-mode cluster --driver-memory 8G --class org.apache.spark.examples.JavaWordCount /home/hadoop/spark/lib/spark-examples-1.3.1-hadoop2.4.0.jar s3://mybucket/data/ 

Tuttavia, se mi tolgo la '--driver memoria 8G', il compito viene assegnato 2 esecutori e finisce correttamente.

Quindi, qual è il problema con la memoria del driver che impedisce al mio compito di ottenere gli esecutori?

Il driver deve essere eseguito sul nodo master del cluster insieme al contenitore master del filato come spiegato here?

Come posso dare più memoria al mio driver di scintilla? (Dove si accumulano e altre operazioni utili)

risposta

17

La soluzione per massimizzare l'utilizzo del cluster consiste nel dimenticare il parametro '-x' durante l'installazione di spark su EMR e per regolare manualmente la memoria e i core degli executors.

Questo post fornisce una spiegazione piuttosto buona di come viene eseguita l'allocazione delle risorse durante l'esecuzione di Spark su YARN.

Una cosa importante da ricordare è che a tutti gli esecutori devono essere assegnate le stesse risorse! Mentre parliamo, Spark non supporta esecutori eterogenei. (Alcuni lavori sono attualmente in fase di supporto per GPU ma è un altro argomento)

Quindi, per ottenere la massima memoria allocata al driver mentre si ottimizza la memoria per gli executors, dovrei dividere i miei nodi come questo (questo slideshare offre buoni screenshot a pagina 25):

  • nodo 0 - master (Filati gestore delle risorse)
  • Nodo 1 - NodeManager (Container (driver) + Container (esecutore))
  • Nodo 2 - NodeManager (Container (esecutore) + Container (Executor))

NOTA: Un'altra opzione potrebbe essere spark-submit con --master yarn --deploy-mode client dal nodo master 0. C'è qualche esempio di contatore questa è una cattiva idea?

Nel mio esempio, posso avere al massimo 3 esecutori di 2 vcores con 4736 MB ciascuno + un driver con le stesse specifiche.

4736 la memoria è derivata dal valore di yarn.nodemanager.resource.memory-mb definito in /home/hadoop/conf/yarn-site.xml. Su un m3.xlarge, esso è impostato su 11520 MB (vedi here per tutti i valori associati ad ogni tipo di istanza)

Poi, otteniamo:

(11.520-1.024)/2 (esecutori per nodi) = 5248 => 5120 (arrotondato dal 256 mb incremento definiti yarn.scheduler.minimum-assegnazione-mb)

7% * 5120 = 367 arrotondato a 384 (overhead di memoria) diventerà 10% in scintilla 1.4

5120 - 384 = 4736

Altri link interessanti:

+0

Sì, fondamentalmente l'utente ha bisogno di sintonizzare le impostazioni per abbinare ciò che si desidera. I documenti di Spark riguardanti il ​​lancio sul filo parlano bene. – ChristopherB

+0

L'analisi del nodo implica che il driver non viene eseguito sul gestore risorse (Istanza master in EMR). È questo il caso? (cercando di capovolgerlo) (quando si esegue come cluster di filati) – noli

+0

Sì, questo è quello che dice .. A meno che non mi sbagli, non ho visto nulla in esecuzione sul nodo principale quando si utilizza la modalità cluster-cluster . –

2

Il problema riguarda le aspettative su come Spark funziona su YARN. Quando Spark viene eseguito con una modalità di distribuzione di cluster o master impostata su filato cluster, il driver è non eseguito sul nodo master ma nel contenitore Application Master su uno dei nodi slave.Per ulteriori dettagli, vedere https://spark.apache.org/docs/latest/running-on-yarn.html

Mi aspetto che ciò che sta accadendo è che il cluster non può soddisfare i requisiti di memoria per il driver (ricordate che la memoria effettivamente richiesta dal cluster è ciò che chiedete più un overhead) e quindi aspettando per sempre di allocare l'Application Master su cui verrà eseguito il driver o per gli executors.

Per fornire al driver la quantità di memoria richiesta, è necessario utilizzare slave aggiuntivi per fornire allo stesso tempo risorse per il driver e gli esecutori basati su cluster. Con il sovraccarico sul driver, ho il sospetto che potrebbe essere necessario utilizzare un tipo di istanza con più memoria. Quando si richiede 8G per il conducente, dare un'occhiata al log del gestore risorse e verificare l'importo reale richiesto.

Per eseguire il driver sul nodo master, la modalità di distribuzione dovrebbe essere client. Questo può ancora essere fatto con i passaggi EMR se si utilizza un passaggio per chiamare uno script per localizzare i jar del driver sul nodo master e quindi il passo successivo può chiamare spark-submit set per il client in modalità deployment e fare riferimento al file master sul file master locale sistema.

+0

Quindi mi aspetto di avere almeno un executor su una configurazione di 3 macchine. Quando guardo l'interfaccia utente di spark nella sezione executor, vedo spesso un solo driver e nessun esecutore. E perché Spark non sta eseguendo nulla sul driver stesso? Sembra ragionevole usare l'autista per un po 'di lavoro. Tuttavia, sembra che non stia facendo nulla secondo l'interfaccia utente della scintilla. –

+0

Il driver non è per il lavoro di executor/parallelo. Solo per tutto ciò che è stato raccolto e per la gestione dell'interazione/pianificazione di SparkContext. Con una configurazione a 3 macchine ci sarebbero solo 2 nodi per contenitori. Se si vede il driver ma nessun esecutore ... dovrebbe esaminare più da vicino i registri dal driver e dal gestore risorse per determinare il motivo per cui un esecutore non può presentarsi sul secondo nodo. – ChristopherB

0

post di Michel Lemay è buona valori di fondo, e lui dà una risposta per 1 particolare configurazione del cluster. Ho incorporato quella logica in un foglio di calcolo che mostrerà le migliori opzioni per qualsiasi cluster. Per utilizzare, compilare il numero di nodi nel cluster, il numero di core/nodo virtuali e la quantità di memoria allocabile/nodo. Dopo aver eseguito questa operazione, il foglio fornirà le opzioni per i comandi di avvio che utilizzeranno completamente il cluster per la modalità cluster client & per 1, 2, 4 e 8 esecutori per nodo. Ho evidenziato la riga corrispondente a 2 esecutori per nodo in quanto questa è stata sempre la migliore opzione nei miei test. Sentiti libero di copiare questo foglio o aggiungere schede per diversi tipi di cluster a tuo piacimento.

https://docs.google.com/spreadsheets/d/1VH7Qly308hoRPu5VoLIg0ceolrzen-nBktRFkXHRrY4/edit?usp=sharing

0

Ecco come ottenere il problema:

Impostando spark.executor.memory + driver di memoria al di sotto del totale di un dato nodo master, poi filato è in grado di collocare sia il Master e l'esecutore su un determinato nodo. Sacrificherai parte della memoria persa sugli altri nodi, ma è più importante che io abbia le CPU in esecuzione. Ecco un esempio (su r3.8xlarge):

aws emr add-steps --cluster-id j-1234 --steps Type=Spark,Name=foob3,Args=[--conf,spark.memory.fraction=0.95,--conf,spark.memory.storageFraction=0.1,--conf,spark.yarn.executor.memoryOverhead=8000,--conf,spark.executor.memory=200g,--conf,spark.executor.cores=32,--conf,spark.executor.instances=4,--conf,spark.dynamicAllocation.enabled=false,--class,myclass.Foo,--deploy-mode,cluster,--master,yarn,--driver-memory,10g,s3://myjar-1.0-SNAPSHOT.jar],ActionOnFailure=CONTINUE 
Problemi correlati