https://www.iteblog.com/archives/981
Container is running beyond memory limitshttp://stackoverflow.com/questions/21005643/container-is-running-beyond-memory-limits`
[hadoop] - Container [xxxx] is running beyond physical/virtual memory limits. http://www.cnblogs.com/liuming1992/p/5040262.html
當運行mapreduce的時候,有時候會出現異常信息,提示物理內存或者虛擬內存超出限制,默認情況下:虛擬內存是物理內存的2.1倍。異常信息類似如下:
Container [pid=13026,containerID=container_1449820132317_0013_01_000012] is running beyond physical memory limits. Current usage: 1.0 GB of 1 GB physical memory used; 1.7 GB of 2.1 GB virtual memory used. Killing container. Dump of the process-tree for container_1449820132317_0013_01_000012 : |- PID PPID PGRPID SESSID CMD_NAME USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) RSSMEM_USAGE(PAGES) FULL_CMD_LINE |- 13044 13026 13026 13026 (java) 4479 494 1696595968 271631 /home/hadoop/cdh5.2.4/jdk1.7.0_79/bin/java -Djava.net.preferIPv4Stack=true -xxx
我們可以看到該異常信息是提示物理內存超過限制,但是通過我們查看代碼我們發現我們最終使用的內存沒有達到1G,只有500M-。(具體原因沒有細查)最終我們發現影響這個代碼執行的參數分別是:
參數 | 默認值 | 描述 |
yarn.scheduler.minimum-allocation-mb | 1024 | 每個container請求的最低jvm配置,單位m。如果請求的內存小於該值,那么會重新設置為該值。 |
yarn.scheduler.maximum-allocation-mb | 8192 | 每個container請求的最高jvm配置,單位m。如果大於該值,會被重新設置。 |
yarn.nodemanager.resource.memory-mb | 8192 | 每個nodemanager節點准備最高內存配置,單位m |
yarn.nodemanager.vmem-pmem-ratio | 2.1 | 虛擬內存和物理內存之間的比率,如果提示virtual memory limits的時候,可以將該值調大。 |
yarn.nodemanager.pmem-check-enabled | true | 是否進行物理內存限制比較,設置為false,不會進行大小的比較 |
yarn.nodemanager.vmem-check-enabled | false | 是否進行虛擬內存限制比較。 |
mapreduce.map.memory.mb | 1024 | map內存申請大小,單位m |
mapreduce.reduce.memory.mb | 1024 | reduce內存申請大小,單位m |
mapred.child.java.opts | -Xmx200 | map/reduce執行參數設置,可以參數Hadoop Mapreduce Error: GC overhead limit exceeded |
針對該異常信息,有多種方式進行解決:
第一種:
直接將yarn.nodemanager.pmem-check-enabled和yarn.nodemanager.vmem-check-enabled設置為false,那么可以杜絕異常信息的產生。
第二種:
如果異常信息提示的是virtual memory不夠,那么可以將yarn.nodemanager.vmem-pmem-ratio參數改大,那么也可以避免異常信息的產生。
第三種:
修改mapreduce參數,設置修改如下:
mapreduce.map.memory.mb = (1~2倍) * yarn.scheduler.minimum-allocation-mb
mapreduce.reduce.memory.mb = (1~4倍) * yarn.scheduler.minimum-allocation-mb
1. mapred.child.java.opts = -XmxTm(T數字要小於map和reduce的設置value)
2. mapreduce.map.java.opts=-Xmx(<mapreduce.map.memory.mb)m
mapreduce.reduce.java.opts=-Xmx(<mapreduce.reduce.memory.mb)m
總結:最終運行參數給定的jvm堆大小必須小於參數指定的map和reduce的memory大小,最好為70%以下。
hadoop源碼涉及到地方:
1. org.apache.hadoop.mapred.MapReduceChildJVM.getChildJavaOpts
2. org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl.MonitoringThread.run()<398-465行>(進行內存限制判斷)
3. org.apache.hadoop.yarn.server.nodemanager.containermanager.container.ContainerImpl.LaunchTransition.transition()<647-658行>(進行物理內存和虛擬內存大小限制計算和賦值)
物理內存大小其實就是mapreduce.map.memory.mb和mapreduce.reduce.memory.mb的一個大小值
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
mapred.child.java.opts:當需要處理超大數據(mapper大於10?)最好將值設置成-Xmx1024m或者更高(-Xmx2048m)才能避免出現“核心已轉儲”這種jvm內存溢出的錯誤!!
http://slaytanic.blog.51cto.com/2057708/1101360/
name | value | Description |
hadoop.job.history.location | job歷史文件保存路徑,無可配置參數,也不用寫在配置文件里,默認在logs的history文件夾下。 | |
hadoop.job.history.user.location | 用戶歷史文件存放位置 | |
io.sort.factor | 30 | 這里處理流合並時的文件排序數,我理解為排序時打開的文件數 |
io.sort.mb | 600 | 排序所使用的內存數量,單位兆,默認1,我記得是不能超過mapred.child.java.opt設置,否則會OOM |
mapred.job.tracker | hadoopmaster:9001 | 連接jobtrack服務器的配置項,默認不寫是local,map數1,reduce數1 |
mapred.job.tracker.http.address | 0.0.0.0:50030 | jobtracker的tracker頁面服務監聽地址 |
mapred.job.tracker.handler.count | 15 | jobtracker服務的線程數 |
mapred.task.tracker.report.address | 127.0.0.1:0 | tasktracker監聽的服務器,無需配置,且官方不建議自行修改 |
mapred.local.dir | /data1/hdfs/mapred/local, /data2/hdfs/mapred/local, ... |
mapred做本地計算所使用的文件夾,可以配置多塊硬盤,逗號分隔 |
mapred.system.dir | /data1/hdfs/mapred/system, /data2/hdfs/mapred/system, ... |
mapred存放控制文件所使用的文件夾,可配置多塊硬盤,逗號分隔。 |
mapred.temp.dir | /data1/hdfs/mapred/temp, /data2/hdfs/mapred/temp, ... |
mapred共享的臨時文件夾路徑,解釋同上。 |
mapred.local.dir.minspacestart | 1073741824 | 本地運算文件夾剩余空間低於該值則不在本地做計算。字節配置,默認0 |
mapred.local.dir.minspacekill | 1073741824 | 本地計算文件夾剩余空間低於該值則不再申請新的任務,字節數,默認0 |
mapred.tasktracker.expiry.interval | 60000 | TT在這個時間內沒有發送心跳,則認為TT已經掛了。單位毫秒 |
mapred.map.tasks | 2 | 默認每個job所使用的map數,意思是假設設置dfs塊大小為64M,需要排序一個60M的文件,也會開啟2個map線程,當jobtracker設置為本地是不起作用。 |
mapred.reduce.tasks | 1 | 解釋同上 |
mapred.jobtracker.restart.recover | true | false | 重啟時開啟任務恢復,默認false |
mapred.jobtracker.taskScheduler | org.apache.hadoop.mapred. CapacityTaskScheduler org.apache.hadoop.mapred. JobQueueTaskScheduler org.apache.hadoop.mapred. FairScheduler |
重要的東西,開啟任務管理器,不設置的話,hadoop默認是FIFO調度器,其他可以使用公平和計算能力調度器 |
mapred.reduce.parallel.copies | 10 | reduce在shuffle階段使用的並行復制數,默認5 |
mapred.child.java.opts | -Xmx2048m -Djava.library.path= |
每個TT子進程所使用的虛擬機內存大小 |
tasktracker.http.threads | 50 | TT用來跟蹤task任務的http server的線程數 |
mapred.task.tracker.http.address | 0.0.0.0:50060 | TT默認監聽的httpIP和端口,默認可以不寫。端口寫0則隨機使用。 |
mapred.output.compress | true | false | 任務結果采用壓縮輸出,默認false,建議false |
mapred.output.compression.codec | org.apache.hadoop.io. compress.DefaultCodec |
輸出結果所使用的編解碼器,也可以用gz或者bzip2或者lzo或者snappy等 |
mapred.compress.map.output | true | false | map輸出結果在進行網絡交換前是否以壓縮格式輸出,默認false,建議true,可以減小帶寬占用,代價是會慢一些。 |
mapred.map.output.compression.codec | com.hadoop.compression. lzo.LzoCodec |
map階段壓縮輸出所使用的編解碼器 |
map.sort.class | org.apache.hadoop.util. QuickSort |
map輸出排序所使用的算法,默認快排。 |
mapred.hosts | conf/mhost.allow | 允許連接JT的TT服務器列表,空值全部允許 |
mapred.hosts.exclude | conf/mhost.deny | 禁止連接JT的TT列表,節點摘除是很有作用。 |
mapred.queue.names | ETL,rush,default | 配合調度器使用的隊列名列表,逗號分隔 |
mapred.tasktracker.map. tasks.maximum |
12 | 每服務器允許啟動的最大map槽位數。 |
mapred.tasktracker.reduce. tasks.maximum |
6 | 每服務器允許啟動的最大reduce槽位數 |
http://blog.csdn.net/lalaguozhe/article/details/9076895
前一陣子發現用戶提交的Hive query和Hadoop job會導致集群的load非常高,經查看配置,發現很多用戶擅自將mapred.child.Java.opts設置的非常大,比如-Xmx4096m(我們默認設置是-Xmx1024m), 導致了tasktracker上內存資源耗盡,進而開始不斷swap磁盤上數據,load飆升
TaskTracker在spawn一個map/reduce task jvm的時候,會根據用戶JobConf里面的值設定jvm的參數,然后寫入一個taskjvm.sh文件中,然后調用Linux命令"bin/bash -c taskjvm.sh"來執行task,
mapred.child.java.opts就是設定jvm的參數之一,在新版本中已經標注Deprecateded,取而代之的是區分Map task和Reduce task的jvm opts,mapred.map.child.java.opts和mapred.reduce.child.java.opts(默認值為-Xmx200m)
當用戶在不設該值情況下,會以最大1G jvm heap size啟動task,有可能導致OutOfMemory,所以最簡單的做法就是設大參數,並且由於這個值不是final,所以用戶在自己的mapred-site.xml中可以覆蓋默認值。但是如果很多用戶都無限度設置的話,high load問題就來了。
其實在構造JVM Args的過程中,是有另外一個admin參數可以覆蓋用戶端設置的mapreduce.admin.map.child.java.opts, mapreduce.admin.reduce.child.java.opts
經測試,如果相同的jvm arg如果寫在后面,比如"-Xmx4000m -Xmx1000m",后面的會覆蓋前面的,“-Xmx1000m”會最終生效,通過這種方式,我們就可以有限度的控制heap size了
終在mapred-site.xml中加上
<property> <name>mapreduce.admin.map.child.java.opts</name> <value>-Xmx1024m</value> </property> <property> <name>mapreduce.admin.reduce.child.java.opts</name> <value>-Xmx1536m</value> </property>