2014-09-25 136 views
0

我有簡單的映射器和下面這個簡單的減速機(它是由一個外地加盟的兩個大表):Hadoop的內存使用:減少容器運行超出了物理內存限制

protected void reduce(StringLongCompositeKey key, Iterable<Text> values, Context context) 
      throws IOException, InterruptedException {} 
    foreach(Text text : values) { 
     // do some operations with one record and then emit it using context.write 
     // so nothing is storing in memory, one text record is small (mo more then 1000 chars) 
    } 
} 

,但我得到了以下錯誤

14/09/25 17點54分59秒INFO mapreduce.Job:地圖100%減少28%

14/09/25 17點57分14秒INFO mapreduce.Job:任務標識:attempt_1410255753549_9772_r_000020_0,狀態:失敗

Container [pid = 24481,containerID = container_1410255753549_9772_01_001594]超出了物理內存限制。當前使用情況:使用4 GB物理內存4.1 GB;使用4.8 GB的8.4 GB虛擬內存。殺死容器。

有一個細微差別 - )

Iterable<Text> values 

很長!正如我之前所考慮的,並且仍然相信這是事實,Iterable會根據需求加載下一個記錄,並且hadoop處理它不應該成爲問題,而不會消耗大量的RAM。

在洗牌或排序時出現此錯誤嗎?有沒有關於處理長序列的特殊信息?

回答

1

在洗牌或排序時會出現此錯誤嗎?

確實。在代碼實際運行之前,當數據被移動到縮減器時,這似乎正發生在隨機播放階段。

減少百分比的工作方式是0-33%是洗牌階段,數據發送給減速器,33-66%是排序階段,最後33%代表容器運行。

0

似乎洗牌排序內存不足。你可以檢查你的配置,看看你是如何分配內存的。通過使用java.opts,可以確保Reducer的java堆不會聲明所有內存,因爲它還需要OS和核心進程的內存。作爲一個經驗法則,我爲這些留下了512MB。洗牌排序中的內存不足可能與洗牌排序競爭內存有關。降低允許洗牌使用的百分比通常可以解決問題。 Ofc,最好的設置取決於你的設置。

mapreduce.reduce.memory.mb=4096 
mapreduce.reduce.java.opts="-server 
-Xmx3584m -XX:NewRatio=8 -Djava.net.preferIPv4Stack=true" 
mapreduce.reduce.shuffle.input.buffer.percent=0.2