1. 程式人生 > >MapReduce任務Shuffle Error錯誤

MapReduce任務Shuffle Error錯誤

1、錯誤描述
在執行MapReduce任務的時候,出現如下錯誤:
Error: org.apache.hadoop.mapreduce.task.reduce.Shuffle$ShuffleError: error in shuffle in fetcher#1
        at org.apache.hadoop.mapreduce.task.reduce.Shuffle.run(Shuffle.java:134)
        at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:376)
        at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:167)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:396)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1556)
        at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:162)
Caused by: java.lang.OutOfMemoryError: Java heap space
        at org.apache.hadoop.io.BoundedByteArrayOutputStream.<init>(BoundedByteArrayOutputStream.java:56)
        at org.apache.hadoop.io.BoundedByteArrayOutputStream.<init>(BoundedByteArrayOutputStream.java:46)
        at org.apache.hadoop.mapreduce.task.reduce.InMemoryMapOutput.<init>(InMemoryMapOutput.java:63)
        at org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl.unconditionalReserve(MergeManagerImpl.java:297)
        at org.apache.hadoop.mapreduce.task.reduce.MergeManagerImpl.reserve(MergeManagerImpl.java:287)
        at org.apache.hadoop.mapreduce.task.reduce.Fetcher.copyMapOutput(Fetcher.java:411)
        at org.apache.hadoop.mapreduce.task.reduce.Fetcher.copyFromHost(Fetcher.java:341)
        at org.apache.hadoop.mapreduce.task.reduce.Fetcher.run(Fetcher.java:165)


2、解決方案
根據《Hadoop:The Definitive Guide 4th Edition》所述(P203-219),map任務和reduce任務之間要經過一個shuffle過程,該過程複製map任務的輸出作為reduce任務的輸入
具體的來說,shuffle過程的輸入是:map任務的輸出檔案,它的輸出接收者是:執行reduce任務的機子上的記憶體buffer,並且shuffle過程以並行方式執行
引數mapreduce.reduce.shuffle.input.buffer.percent控制執行reduce任務的機子上多少比例的記憶體用作上述buffer(預設值為0.70),引數mapreduce.reduce.shuffle.parallelcopies控制shuffle過程的並行度(預設值為5)
那麼"mapreduce.reduce.shuffle.input.buffer.percent" * "mapreduce.reduce.shuffle.parallelcopies" 必須小於等於1,否則就會出現如上錯誤
因此,我將mapreduce.reduce.shuffle.input.buffer.percent設定成值為0.1,就可以正常運行了(設定成0.2,還是會拋同樣的錯)


另外,可以發現如果使用兩個引數的預設值,那麼兩者乘積為3.5,大大大於1了,為什麼沒有經常丟擲以上的錯誤呢?
1)首先,把預設值設為比較大,主要是基於效能考慮,將它們設為比較大,可以大大加快從map複製資料的速度

2)其次,要丟擲如上異常,還需滿足另外一個條件,就是map任務的資料一下子準備好了等待shuffle去複製,在這種情況下,就會導致shuffle過程的“執行緒數量”和“記憶體buffer使用量”都是滿負荷的值,自然就造成了記憶體不足的錯誤;而如果map任務的資料是斷斷續續完成的,那麼沒有一個時刻shuffle過程的“執行緒數量”和“記憶體buffer使用量”是滿負荷值的,自然也就不會丟擲如上錯誤

另外,如果在設定以上引數後,還是出現錯誤,那麼有可能是執行Reduce任務的程序的記憶體總量不足,可以通過mapred.child.java.opts引數來調節,比如設定mapred.child.java.opts=-Xmx2024m