MapReduce Shuffle调优
操作场景
Shuffle阶段是MapReduce性能的关键部分,包括了从Map task将中间数据写到磁盘一直到Reduce task拷贝数据并最终放到reduce函数的全部过程。这部分Hadoop提供了大量的调优参数。
操作步骤
- Map阶段的调优
- 判断Map使用的内存大小
判断Map分配的内存是否足够,一个简单的办法是查看运行完成的job的Counters中,对应的task是否发生过多次GC,以及GC时间占总task运行时间之比。通常,GC时间不应超过task运行时间的10%,即GC time elapsed (ms)/CPU time spent (ms)<10%。
主要通过如下参数进行调整。
参数入口:
进入Yarn服务参数“全部配置”界面,在搜索框中输入参数名称。具体操作请参考修改集群服务配置参数章节。
建议配置“mapreduce.map.java.opts”参数中“-Xmx”值为“mapreduce.map.memory.mb”参数值的0.8倍。
表1 参数说明 参数
描述
默认值
mapreduce.map.memory.mb
map任务的内存限制。
4096
mapreduce.map.java.opts
map子任务的JVM参数。如果设置,会替代mapred.child.java.opts参数;如果未设置-Xmx,Xmx值从mapreduce.map.memory.mb*mapreduce.job.heap.memory-mb.ratio计算获取。
MRS 3.x之前版本:-Xmx2048M -Djava.net.preferIPv4Stack=true
MRS 3.x及之后版本:
- 集群已开启Kerberos认证:-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false -Djava.security.krb5.conf=${BIGDATA_HOME}/common/runtime/krb5.conf -Dbeetle.application.home.path=${BIGDATA_HOME}/common/runtime/security/config
- 集群未开启Kerberos认证:-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false -Dbeetle.application.home.path=${BIGDATA_HOME}/common/runtime/security/config
- 使用Combiner
在Map阶段,有一个可选过程,将同一个key值的中间结果合并,叫做Combiner。一般将reduce类设置为Combiner即可。通过Combiner,一般情况下可以显著减少Map输出的中间结果,从而减少shuffle过程的网络带宽占用。可通过如下接口为一个任务设置Combiner类。
表2 Combiner设置接口 类名
接口名
描述
org.apache.hadoop.mapreduce.Job
public void setCombinerClass(Class<? extends Reducer> cls)
为Job设置一个Combiner类。
- 判断Map使用的内存大小
- Copy阶段的调优
数据是否压缩:
对Map的中间结果进行压缩,当数据量大时,会显著减少网络传输的数据量,但是也因为多了压缩和解压,带来了更多的CPU消耗。因此需要做好权衡。当任务属于网络瓶颈类型时,压缩Map中间结果效果明显。针对bulkload调优,压缩中间结果后性能提升60%左右。
配置方法:将“mapreduce.map.output.compress”参数值设置为“true”,将“mapreduce.map.output.compress.codec”参数值设置为“org.apache.hadoop.io.compress.SnappyCodec”。
- Merge阶段的调优
通过调整如下参数减少reduce写磁盘的次数。
参数入口:
进入Yarn服务参数“全部配置”界面,在搜索框中输入参数名称。具体操作请参考修改集群服务配置参数章节。
表3 参数说明 参数
描述
默认值
mapreduce.reduce.merge.inmem.threshold
内存合并进程的文件数阈值。累计文件数达到阈值时会发起内存合并及溢出到磁盘。小于等于0的值表示该阈值不生效且仅基于ramfs的内存使用情况来触发合并。
1000
mapreduce.reduce.shuffle.merge.percent
发起内存合并的使用率阈值,表示为分配给映射输出信息的内存的比例(是由mapreduce.reduce.shuffle.input.buffer.percent设置的)。
0.66
mapreduce.reduce.shuffle.input.buffer.percent
shuffle过程中分配给映射输出信息的内存占最大堆大小的比例。
0.70
mapreduce.reduce.input.buffer.percent
Reduce过程中保存映射输出信息的内存相对于最大堆大小的比例。当shuffle结束时,需保证reduce开始前内存中所有剩余的映射输出信息所使用的内存小于该阈值。
0.0