mapreduce 的调优一般都是基于shuffle阶段的。下面就讲讲基本思路。
调优的基本原则就是给 shuffle 阶段尽可能大的内存。但是因为map和reduce函数的执行也需要内存,所以shuffle需要多少内存需要权衡一下,比如尽量避免在 map reduce 用 哈希表等结构对数据进行聚合操作,让 map 和 reduce 占用的内存尽可能小。
map 和 reduce 任务占用的内存是由参数 mapred.child.java.opts 设置的,这个值应该尽可能大,但是要小于节点容器所占据的内存。
在map阶段应该尽量避免多次spill数据到磁盘,map阶段的调优参数:
属性名 | 类型 | 默认值 | 说明 |
mapreduce.task.io.sort.mb | int | 100 | map 输出结果进行排序阶段用到的内存大小,单位是 M |
mapreduce.map.sort.spill.percent | float | 0.80 | map 和 reduce 阶段输出结果保存在内存缓存中,达到这一比例便开始spill 到磁盘 |
mapreduce.task.io.sort.factor | int | 10 | 当对文件进行排序时,一次可以合并的最大文件数量。 |
mapreduce.map.combine.minspills | int | 3 | 如果设置了combiner函数,触发combine动作的最少文件数量。 |
mapreduce.map.out.compress | bolean | false | map 输出结构是否压缩 |
mapreduce.map.output.compress.codec | class name | org.apache.hadoop.io.compress.Default Codec | 对 map 数据结果进行压缩的类 |
mapreduce.shuffle.max.threads | int | 0 | 每个节点上开启的线程数用于将map输出结果传送到reducer。0 代表用Netty框架的默认值,默认为可用的逻辑处理器的2倍 |
reduce 阶段的参数
mapreduce.reduce.shuffle.parallelcopies int 5 将map阶段的输出结果copy到reducer的并行度(线程数)
mapreduce.reduce.shuffle.maxfetchfailures int 10 拉取map阶段输出结果的线程允许失败的最大次数
mapreduce.task.io.sort.factor int 10 一次可以合并的最大文件数量。
mapreduce.reduce.shuffle.input.buffer.percent float 0.70 在shuffle过程的copy phase ,map 端的输出结果占用的堆内存比例。
mapreduce.reduce.shuffle.merge.percent float 0.66
mapreduce.reduce.merge.inmem.threshold int 1000