Il contenitore è in esecuzione oltre i limiti di memoria


85

In Hadoop v1, ho assegnato a ciascuno 7 slot di mappatura e riduttore con dimensioni di 1 GB, i miei mappatori e riduttori funzionano bene. La mia macchina ha una memoria 8G, 8 processori. Ora con YARN, quando si esegue la stessa applicazione sulla stessa macchina, ho ricevuto un errore del contenitore. Per impostazione predefinita, ho queste impostazioni:

  <property>
    <name>yarn.scheduler.minimum-allocation-mb</name>
    <value>1024</value>
  </property>
  <property>
    <name>yarn.scheduler.maximum-allocation-mb</name>
    <value>8192</value>
  </property>
  <property>
    <name>yarn.nodemanager.resource.memory-mb</name>
    <value>8192</value>
  </property>

Mi ha dato un errore:

Container [pid=28920,containerID=container_1389136889967_0001_01_000121] is running beyond virtual memory limits. Current usage: 1.2 GB of 1 GB physical memory used; 2.2 GB of 2.1 GB virtual memory used. Killing container.

Ho quindi provato a impostare il limite di memoria in mapred-site.xml:

  <property>
    <name>mapreduce.map.memory.mb</name>
    <value>4096</value>
  </property>
  <property>
    <name>mapreduce.reduce.memory.mb</name>
    <value>4096</value>
  </property>

Ma continua a ricevere errore:

Container [pid=26783,containerID=container_1389136889967_0009_01_000002] is running beyond physical memory limits. Current usage: 4.2 GB of 4 GB physical memory used; 5.2 GB of 8.4 GB virtual memory used. Killing container.

Sono confuso perché l'attività della mappa necessita di così tanta memoria. A quanto mi risulta, 1 GB di memoria è sufficiente per la mia attività di mappa / riduzione. Perché quando assegno più memoria al contenitore, l'attività ne utilizza di più? È perché ogni attività ottiene più suddivisioni? Ritengo sia più efficiente ridurre un po 'le dimensioni del contenitore e creare più contenitori, in modo che più attività vengano eseguite in parallelo. Il problema è come posso assicurarmi che a ogni contenitore non vengano assegnate più suddivisioni di quante ne possa gestire?



Ciao ! la tua configurazione 'filato.nodemanager.vmem-pmem-ratio = 2'?
sprite

Risposte:


102

È inoltre necessario configurare correttamente le allocazioni di memoria massima per MapReduce. Da questo tutorial di HortonWorks :

[...]

Ogni macchina nel nostro cluster dispone di 48 GB di RAM. Parte di questa RAM dovrebbe essere> riservata per l'utilizzo del sistema operativo. Su ogni nodo, assegneremo 40 GB di RAM per> YARN da utilizzare e manterremo 8 GB per il sistema operativo

Per il nostro cluster di esempio, abbiamo la RAM minima per un contenitore (filato.scheduler.minimum-allocation-mb) = 2 GB. Assegneremo quindi 4 GB per i contenitori delle attività di mappa e 8 GB per i contenitori delle attività di riduzione.

In mapred-site.xml:

mapreduce.map.memory.mb: 4096

mapreduce.reduce.memory.mb: 8192

Ogni container eseguirà JVM per le attività di mappatura e riduzione. La dimensione dell'heap JVM deve essere impostata su un valore inferiore alla memoria Mappa e Riduci definita sopra, in modo che siano entro i limiti della memoria del contenitore allocata da YARN.

In mapred-site.xml:

mapreduce.map.java.opts: -Xmx3072m

mapreduce.reduce.java.opts: -Xmx6144m

Le impostazioni precedenti configurano il limite superiore della RAM fisica che verrà utilizzata dalle attività di mappatura e riduzione .

Riassumendo:

  1. In YARN, dovresti usare le mapreduceconfigurazioni, non mapredquelle. EDIT: questo commento non è più applicabile ora che hai modificato la tua domanda.
  2. Quello che stai configurando è in realtà quanto vuoi richiedere, non qual è il massimo da allocare.
  3. I limiti massimi vengono configurati con le java.optsimpostazioni elencate sopra.

Infine, potresti voler controllare quest'altra domanda SO che descrive un problema simile (e una soluzione).


Sì. Impostando mapreduce.map.java.optse mapreduce.reduce.java.optsrisolvendo il mio problema. Sai se la memoria effettiva assegnata all'attività è definita solo da mapreduce.map/reduce.memory.mb? In che modo yarn.scheduler.minimum-allocation-mbinfluisce sull'assegnazione effettiva della memoria?
Lishu

@lishu, se questo ha aiutato, allora per favore accetta la risposta. Riguardo alla tua ultima domanda, l'impostazione del filato si applica a qualsiasi allocazione di contenitori nel cluster; questo include mappare e ridurre le attività, ma anche altre attività da altri tipi di applicazioni. Le impostazioni di mapreduce si applicano solo ai lavori di mapreduce.
cabad

@cabad, sviluppo una libreria che Lishu sta usando. Mi chiedevo se cambieresti qualcosa nella tua risposta sapendo che l'attività MR sta generando un processo che in realtà alloca la maggior parte della memoria (streaming hadoop). Certamente l'impostazione Xmx non influisce sul processo esterno, poiché non è un programma java. Grazie per l'aiuto.
piccolbo

2
Ora c'è un utile strumento di Hortonworks chiamato hdp-configuration-utils per ottenere i valori consigliati. Scaricalo
selle

1
Se l'applicazione della corretta configurazione della memoria non ha risolto il problema (come nel mio caso, in realtà ha funzionato su un hadoop in esecuzione su Ubuntu ma non su CentOS) prova a disabilitare il controllo di vmem
Bakhshi

47

C'è un controllo posto a livello di filato per il rapporto di utilizzo della memoria virtuale e fisica. Il problema non è solo che la VM non ha memoria fisica sufficiente. Ma è perché l'utilizzo della memoria virtuale è più del previsto per una data memoria fisica.

Nota : questo sta accadendo su Centos / RHEL 6 a causa della sua allocazione aggressiva della memoria virtuale.

Può essere risolto da:

  1. Disabilitare il controllo dell'utilizzo della memoria virtuale impostando filato.nodemanager.vmem-check-enabled su false ;

  2. Aumenta il rapporto VM: PM impostando il rapporto yarn.nodemanager.vmem-pmem su un valore più alto.

Riferimenti :

https://issues.apache.org/jira/browse/HADOOP-11364

http://blog.cloudera.com/blog/2014/04/apache-hadoop-yarn-avoiding-6-time-consuming-gotchas/

Aggiungi la seguente proprietà in filato-site.xml

 <property>
   <name>yarn.nodemanager.vmem-check-enabled</name>
    <value>false</value>
    <description>Whether virtual memory limits will be enforced for containers</description>
  </property>
 <property>
   <name>yarn.nodemanager.vmem-pmem-ratio</name>
    <value>4</value>
    <description>Ratio between virtual memory to physical memory when setting memory limits for containers</description>
  </property>

15

Ho avuto un problema molto simile usando HIVE in EMR. Nessuna delle soluzioni esistenti ha funzionato per me, ovvero nessuna delle configurazioni di mapreduce ha funzionato per me; e nemmeno l'impostazione yarn.nodemanager.vmem-check-enabledsu falso.

Tuttavia, ciò che ha finito per funzionare è stato l'impostazione tez.am.resource.memory.mb, ad esempio:

hive -hiveconf tez.am.resource.memory.mb=4096

Un'altra impostazione da considerare è il tweaking yarn.app.mapreduce.am.resource.mb


Um @hiroprotagonist, sai se il "tweaking" del parametro del filato deve avvenire prima dell'avvio di YARN o se viene utilizzato solo al momento della domanda (e potrebbe essere modificato da un lavoro all'altro)?
Judge Mental

1
sono stato in grado di impostare al momento dell'applicazione. in particolare, all'interno della console interattiva hive.
iroprotagonista

8

Non posso commentare la risposta accettata, a causa della scarsa reputazione. Tuttavia, vorrei aggiungere, questo comportamento è di progettazione. Il NodeManager sta uccidendo il tuo contenitore. Sembra che tu stia cercando di utilizzare lo streaming hadoop che è in esecuzione come processo figlio dell'attività di riduzione della mappa. Il NodeManager monitora l'intero albero del processo dell'attività e se consuma più memoria rispetto al massimo impostato in mapreduce.map.memory.mb o mapreduce.reduce.memory.mb rispettivamente, ci aspetteremmo che il Nodemanager uccida l'attività, altrimenti il tuo compito è rubare la memoria che appartiene ad altri contenitori, che non vuoi.


1

Mentre lavoravo con Spark in EMR avevo lo stesso problema e l'impostazione maximizeResourceAllocation=trueha funzionato; spero che aiuti qualcuno. Devi impostarlo quando crei il cluster. Dai documenti EMR:

aws emr create-cluster --release-label emr-5.4.0 --applications Name=Spark \
--instance-type m3.xlarge --instance-count 2 --service-role EMR_DefaultRole --ec2-attributes InstanceProfile=EMR_EC2_DefaultRole --configurations https://s3.amazonaws.com/mybucket/myfolder/myConfig.json

Dove dovrebbe dire myConfig.json:

[
  {
    "Classification": "spark",
    "Properties": {
      "maximizeResourceAllocation": "true"
    }
  }
]

1

Abbiamo anche affrontato questo problema di recente. Se il problema è relativo alla memoria del mappatore, ci sono un paio di cose che vorrei suggerire che devono essere controllate.

  • Controlla se il combinatore è abilitato o no ? Se sì, significa che la logica di riduzione deve essere eseguita su tutti i record (output del mapper). Questo accade in memoria. In base alla tua applicazione devi controllare se abilitare il combinatore aiuta o meno. Il compromesso è tra i byte di trasferimento di rete e il tempo impiegato / memoria / CPU per la logica di riduzione sul numero "X" di record.
    • Se ritieni che il combinatore non abbia un grande valore, disabilitalo.
    • Se hai bisogno di combinatore e 'X' è un numero enorme (diciamo milioni di record), considera la possibilità di modificare la logica di divisione (per i formati di input predefiniti usa una dimensione di blocco inferiore, normalmente 1 dimensione di blocco = 1 divisione) per mappare un numero inferiore di record a un mappatore unico.
  • Numero di record in fase di elaborazione in un singolo mappatore. Ricorda che tutti questi record devono essere ordinati in memoria (l'output del mapper è ordinato). Considera l' idea di impostare mapreduce.task.io.sort.mb (il valore predefinito è 200 MB) su un valore più alto, se necessario. mapred-configs.xml
  • Se uno qualsiasi dei precedenti non ha aiutato, prova a eseguire la logica del mapper come applicazione standalone e profilare l'applicazione utilizzando un Profiler (come JProfiler) e vedere dove viene utilizzata la memoria. Questo può darti ottime informazioni.

1

Esecuzione di filato su sottosistema Windows Linux con sistema operativo Ubunto, errore "esecuzione oltre i limiti di memoria virtuale, contenitore di uccisione" L'ho risolto disabilitando il controllo della memoria virtuale nel file filato-site.xml

<property> <name>yarn.nodemanager.vmem-check-enabled</name> <value>false</value> </property> 

Su WSL, il messaggio di errore ha numeri assurdi (almeno per me): "... è in esecuzione oltre i limiti di memoria virtuale. Utilizzo corrente: 338,8 MB di 2 GB di memoria fisica utilizzata; 481,1 GB di 4,2 GB di memoria virtuale utilizzata. Killing container . "
Samik R

@ SamikR Sì, ho una situazione simile, immagino che non siano i problemi di hadoop, sono i problemi di WSL. Forse ho bisogno di trasferire la demo su un vero computer con sistema operativo Linux
Bingoabs

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.