1. 程式人生 > >Hadoop YARN中記憶體的設定

Hadoop YARN中記憶體的設定

在YARN中,資源管理由ResourceManager和NodeManager共同完成,其中,ResourceManager中的排程器負責資源的分配,而NodeManager則負責資源的供給和隔離。ResourceManager將某個NodeManager上資源分配給任務(這就是所謂的“資源排程”)後,NodeManager需按照要求為任務提供相應的資源,甚至保證這些資源應具有獨佔性,為任務執行提供基礎的保證,這就是所謂的資源隔離。

基於以上考慮,YARN允許使用者配置每個節點上可用的實體記憶體資源,注意,這裡是“可用的”,因為一個節點上的記憶體會被若干個服務共享,比如一部分給YARN,一部分給HDFS,一部分給HBase等,YARN配置的只是自己可以使用的,配置引數如下:

(1)yarn.nodemanager.resource.memory-mb

表示該節點上YARN可使用的實體記憶體總量,預設是8192(MB),注意,如果你的節點記憶體資源不夠8GB,則需要調減小這個值,而YARN不會智慧的探測節點的實體記憶體總量。

(2)yarn.nodemanager.vmem-pmem-ratio

任務每使用1MB實體記憶體,最多可使用虛擬記憶體量,預設是2.1。

(3) yarn.nodemanager.pmem-check-enabled

是否啟動一個執行緒檢查每個任務正使用的實體記憶體量,如果任務超出分配值,則直接將其殺掉,預設是true。

(4) yarn.nodemanager.vmem-check-enabled

是否啟動一個執行緒檢查每個任務正使用的虛擬記憶體量,如果任務超出分配值,則直接將其殺掉,預設是true。

(5)yarn.scheduler.minimum-allocation-mb

單個任務可申請的最少實體記憶體量,預設是1024(MB),如果一個任務申請的實體記憶體量少於該值,則該對應的值改為這個數。

(6)yarn.scheduler.maximum-allocation-mb

單個任務可申請的最多實體記憶體量,預設是8192(MB)。

預設情況下,YARN採用了執行緒監控的方法判斷任務是否超量使用記憶體,一旦發現超量,則直接將其殺死。由於Cgroups對記憶體的控制缺乏靈活性(即任務任何時刻不能超過記憶體上限,如果超過,則直接將其殺死或者報OOM),而Java程序在建立瞬間記憶體將翻倍,之後驟降到正常值,這種情況下,採用執行緒監控的方式更加靈活(當發現程序樹記憶體瞬間翻倍超過設定值時,可認為是正常現象,不會將任務殺死),因此YARN未提供Cgroups記憶體隔離機制。

可以使用如下命令在提交任務時動態設定:

hadoop jar <jarName> -D mapreduce.reduce.memory.mb=5120

e.g.

[[email protected] hadoop-2.5.2]$ ./bin/hadoop jar /home/hadoop/jar-output/TestLoop-1024M.jar -D mapreduce.map.memory.mb=5120 AESEnTest 1024 1 1

 後面的1024及兩個1均為jar的輸入引數。

Hadoop2.5.2搭建好之後,執行寫好的MapReduce程式出現如下問題:

Container [pid=24156,containerID=container_1427332071311_0019_01_000002] is running beyond physical memory limits. Current usage: 2.1 GB of 2 GB physical memory used; 2.7 GB of 4.2 GB virtual memory used. Killing container.
Dump of the process-tree for container_1427332071311_0019_01_000002 :
|- PID PPID PGRPID SESSID CMD_NAME USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) RSSMEM_USAGE(PAGES) FULL_CMD_LINE
|- 24156 2787 24156 24156 (bash) 0 0 108646400 296 /bin/bash -c /usr/java/jdk1.7.0_45/bin/java -Djava.net.preferIPv4Stack=true -Dhadoop.metrics.log.level=WARN -Xmx2048m -Djava.io.tmpdir=/home/hadoop/hadoop-2.5.2/hadoop-hadoop/nm-local-dir/usercache/hadoop/appcache/application_1427332071311_0019/container_1427332071311_0019_01_000002/tmp -Dlog4j.configuration=container-log4j.properties -Dyarn.app.container.log.dir=/home/hadoop/hadoop-2.5.2/logs/userlogs/application_1427332071311_0019/container_1427332071311_0019_01_000002 -Dyarn.app.container.log.filesize=0 -Dhadoop.root.logger=INFO,CLA org.apache.hadoop.mapred.YarnChild 192.168.199.93 33497 attempt_1427332071311_0019_m_000000_0 2 1>/home/hadoop/hadoop-2.5.2/logs/userlogs/application_1427332071311_0019/containe...

分析:

根據前面所述的記憶體配置相關理論知識,我們可以總結如下:

(RM, Resource Manager; NM, Node Manager; AM, Application Manager)

RM記憶體資源配置——兩個引數(yarn-site.xml)

<property>
<description>The minimum allocation for every container request at the RM,
in MBs. Memory requests lower than this won‘t take effect,
and the specified value will get allocated at minimum.</description>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>1024</value>
</property>


<property>
<description>The maximum allocation for every container request at the RM,
in MBs. Memory requests higher than this won‘t take effect,
and will get capped to this value.</description>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>8192</value>
</property>

它們表示單個容器可以申請的最小與最大記憶體。

NM(yarn-site.xml)

<property>
<description>Amount of physical memory, in MB, that can be allocated
for containers.</description>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>8192</value>
</property>

<property>
<description>Ratio between virtual memory to physical memory when
setting memory limits for containers. Container allocations are
expressed in terms of physical memory, and virtual memory usage
is allowed to exceed this allocation by this ratio.
</description>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>2.1</value>
</property>

前者表示單個節點可用的最大記憶體,RM中的兩個值都不應該超過該值。

後者表示虛擬記憶體率,即佔task所用記憶體的百分比,預設為2.1.

AM(mapred-site.xml)

mapreduce.map.memory.mb

mapreduce.reduce.memory.mb

指定map和reduce task的記憶體大小,該值應該在RM的最大最小container之間。如果不設定,則預設用以下規則進行計算:max{MIN_Container_Size,(Total Available RAM/containers)}。

一般地,reduce設定為map的兩倍。

AM的其他引數設定:

mapreduce.map.java.opts

mapreduce.reduce.java.opts

這兩個引數是偽需要執行JVM程式(java,scala等)準備,通過這兩個引數可以向JVM中傳遞引數,與記憶體有關的是-Xmx, -Xms等選項,數值的大小應該要再AM中的map.mb和reduce.mb之間。

對如上問題,我選擇使用以下方式來解決:(根據提交的job動態設定mapreduce.map.memory.mb的值)

[[email protected] hadoop-2.5.2]$ ./bin/hadoop jar /home/hadoop/jar-output/TestLoop-1024M.jar -D mapreduce.map.memory.mb=5120 AESEnTest 1024 1 1

 參考資料:

https://altiscale.zendesk.com/hc/en-us/articles/200801519-Configuring-Memory-for-Mappers-and-Reducers-in-Hadoop-2

http://stackoverflow.com/questions/21005643/container-is-running-beyond-memory-limits

http://dongxicheng.org/mapreduce-nextgen/hadoop-yarn-memory-cpu-scheduling/