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:121)
at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:379)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:157)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1408)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:152)
Caused by: java.lang.OutOfMemoryError: Java heap space
at org.apache.hadoop.io.BoundedByteArrayOutputStream.(BoundedByteArrayOutputStream.java:58)
at org.apache.hadoop.io.BoundedByteArrayOutputStream.(BoundedByteArrayOutputStream.java:45)
at org.apache.hadoop.mapreduce.task.reduce.InMemoryMapOutput.(InMemoryMapOutput.java:63)
百度了一番配置如下
mapreduce.reduce.shuffle.memory.limit.percent
单个shuffle能够消耗的内存占reduce所有内存的比例,默认是0.25,后来我把它设置0.05 但是最大优化百分比我也不知道
mapreduce.reduce.java.opts
设置堆内催 集群中单台机器内存最小的最大内存为8G 设置 内存一般为8G * 2/3
mapreduce.reduce.shuffle.input.buffer.percent
设置shuffle比例,默认shuffle比例是0.70,可降低这个比例 我设置为0.4
job.setNumReduceTasks(12);
合适的reduce task数量是0.95或者0.75* ( nodes * mapred.tasktracker.reduce.tasks.maximum)
因为16台机器就动态设置12个reduce
就不会出现以上错误了。
主要原因 是shuffle时如果数据过大经常会发生OutOfMemory,这时可以适当调小相应的参数,比如减少每个fetch占内存的百分比让fetch的输出直接进入磁盘
在mapReduce 输出map阶段 key 和value 尽量不要new Text()如果那样会创建很多对象,垃圾回收也很慢
另外输出的时候尽量输出值是有效内容,过滤不需要传递的数据,减小网络IO消耗。
context.write(day, new Text(content));