理论
Reduce Task会启动多个拷贝线程从每个Map Task上去读取相应的中间结果,具体的拷贝线程数目由参数"mapreduce.reduce.shuffle.parallelcopies"(默认为5)指定,对于每个待拷贝的文件,如果文件大小小于一定阈值A,则将其放在内存中,否则以文件的形式存放在磁盘上,如果内存中文件满足一定条件D,则会将这些数据写入磁盘,而当磁盘上文件数目达到mapreduce.task.io.sort.factor(默认是10)时,进行一次合并。
阈值A为:
heapsize * {mapreduce.reduce.shuffle.input.buffer.percent} *{mapreduce.reduce.shuffle.memory.limit.percent}
其中,heapsize是通过参数"mapreduce.reduce.java.opts"指定的,默认是200MB,mapreduce.reduce.shuffle.input.buffer.percent默认值为0.7,mapreduce.reduce.shuffle.memory.limit.percent默认0.25。
条件D为以下两个条件中任意一个:
内存使用率(总的可用内存为heapsize * {mapreduce.reduce.shuffle.input.buffer.percent})达到mapreduce.reduce.shuffle.merge.percent(默认我0.66)
内存中该文件数目超过 mapreduce.reduce.merge.inmem.threshold(默认是1000)。
实践
reduce shuffle OOM问题
项目配置中:
mapreduce.reduce.shuffle.parallelcopies=10
mapreduce.reduce.java.opts=8.2
mapreduce.reduce.shuffle.input.buffer.percent=0.7
mapreduce.reduce.shuffle.memory.limit.percent=0.25
通过计算判断为何OOM:
8.2*0.7*0.25*10=14.20 > 8.2
(所以OOM),所以我们可以调整mapreduce.reduce.shuffle.parallelcopies=5,mapreduce.reduce.shuffle.input.buffer.percent=0.5来使其不OOM。