hive報錯:running beyond physical memory limits. Current usage: 2.0 GB of 2 GB physica終極解決方式

1.案例描述: 

       hive有個定時任務平時正常,沒有啥問題,正常一般大概執行1個小時左右,但是今天突然報錯了,報錯代碼::running beyond physical memory limits. Current usage: 2.0 GB of 2 GB physical memory used; 3.9 GB of 4.2 GB virtual memory used. Killing container。

2.分析解決

      看報錯日誌,顯示說是內存不夠,container分配的2g物理內存已經使用完了,另外虛擬內存4.2g已經使用了3.9g。所以任務被殺死。網上找了一些問題的排查,比如說調整增加了map和reduce的內存,,設置虛擬內存的比率,取消虛擬內存的檢查等等,但是其實好多都沒有用,要具體問題具體分析。下面具體分析一下。

 1.查看大數據集羣配置爲每個container分配到內存的區間,從下面參數的結果可知,我們公司yarn的配置爲每個container可申請的內存區間是1g-8g之間。具體每個container實際分配多少內存要看實際平臺資源的負載情況 ,以及任務的優先級等因素。甚至有種方法說增加下面set yarn.scheduler.minimum-allocation-mb 參數的值,即將每個container的分配內存區間值調大。但是實際上這個值要通過yarn-site.xml文件進行配置,並且需要重啓集羣纔會生效,而實際開發中,這種方法不太可能實現。

1.查看yarn爲每個container分配的內存區間
hive>set yarn.scheduler.minimum-allocation-mb;
    yarn.scheduler.minimum-allocation-mb=1024
hive>set yarn.scheduler.maximum-allocation-mb;
yarn.scheduler.maximum-allocation-mb=8192

  2.從下面看到集羣的配置爲每個maptask和reduce task可使用的內存大下默認爲2g。所以這個時候,如果是因爲平臺資源緊張造成部分任務因內存不夠而失敗(之前很多時候可以正常跑成功的任務)。這時候單方面調大mapreduce.map.memory.mb和mapreduce.reduce.memory.mb的值沒有任何意義,因爲儘管每個container可以分配的內存是1-8g,但現在因爲集羣資源緊張可能分配的內存很小,比如小於2個g,那麼你在調大運行在container上到map和reduce可使用內存,沒有任何意義。有一種情況調大mapreduce.map.memory.mb和mapreduce.reduce.memory.mb的值有用,那就是平臺資源很豐富,每個container實際分配的內存很大,比如6個g。這樣會加快程序的運行,但值太大也會造成資源的浪費。

1.查看每個map,reduce默認使用內存的配置大小
hive>set mapreduce.map.memory.mb;
     mapreduce.map.memory.mb=2048
hive>set mapreduce.reduce.memory.mb;
mapreduce.reduce.memory.mb=2048

3.增加虛擬內存的虛擬化比率

 通過下面可知,默認每個maptask和reudcetask虛擬化的內存比例是2.1。這裏公司集羣每個map,reduce設置的默認內存使用大小爲2g。所以虛擬內存最大2.1*2=4.2g(上面報錯4.2g的來源:3.9 GB of 4.2 GB virtual memory used.),而且這個參數也是通過yarn-site.xml進行配置。其實實際開發中可以對應的配置大些。

hive (default)> set yarn.nodemanager.vmem-pmem-ratio;
yarn.nodemanager.vmem-pmem-ratio=2.1

4. 配置yarn不內存檢查

 通過yarn-site.xml文件將yarn.nodemanager.vmem-check-enabled設置爲false,然後重啓集羣。但是這種不建議,可能會造成內存泄露。

hive (default)> set yarn.nodemanager.vmem-check-enabled;
yarn.nodemanager.vmem-check-enabled=true

5.增加map和reduce的個數

      很顯然,此舉是將每個map和reduce的工作量降小了,可以起到一定作用。一般maptask的個數由文件大小,切片信息等確定,而reduce的個數由最終需要聚合的結果決定,如果增加過多,會產生多個小文件。

       1.增加map的個數,可以通過設置切片信息大小,因爲一般一個切片啓動一個maptask。如下公司每個block的大小是128Mb,所以我們可以將   set mapred.max.split.size 成64Mb.這樣一個塊用兩個task執行。

hive>set dfs.block.size;
    dfs.block.size=134217728

     2.增加reduce數量 可以通過:set  hive.exec.reducers.bytes.per.reducer配置

6.所以分析了一下,實際公司開發中,配到這種情況,重啓集羣也不太靠譜的情況下,只能檢查優化一下自己的程序了。

    1.一般可以給任務設置失敗重試次數,自動多試幾次可能會成功。

    2.檢查程序是否有數據傾斜的問題,一般來說大多數這種情況都是數據傾斜造成的。除非是公司的集羣參數配置的不合理,那麼可以修改一下,適當按照上面的情況增加一下值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章