前一陣子發現用戶提交的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>
構造child java opts的call stack:
不過這種方式只是限定了task的jvm heap最大限制,如果用戶hive query優化不夠好還是會拋出OOM,其實是把問題拋給了用戶,
接下來還要和用戶一起看下到底是哪些query會占用如此大memory,看看有沒有進一步優化的空間