Hadoop 调优之 MapReduce 调优篇

前言

本文隶属于专栏《1000个问题搞定大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

本专栏目录结构和参考文献请见1000个问题搞定大数据技术体系

姊妹篇

Hadoop 调优之 Linux 操作系统调优篇
Hadoop 调优之 HDFS 调优篇
Hadoop 调优之 YARN 调优篇
Hive 如何进行企业级调优?

正文

使用 Hadoop 进行大数据运算,当数据量极大时,那么对 MapReduce 性能的调优重要性不言而喻,尤其是 Shuffle 过程中的参数配置对作业的总执行时间影响特别大。

下面总结一些和 MapReduce 相关的性能调优方法,主要从 5 个方面考虑:

数据输入、 Map 阶段、 Reduce 阶段、 Shuffle 阶段和其他调优属性

1. 数据输入

在执行 MapReduce 任务前,将小文件进行合并,大量的小文件会产生大量的 Map 任务,増大 Map 任务装载的次数,而任务的装载比较耗时,从而导致 MapReduce 运行速度较慢。

因此采用 CombineTextInputFormat 来作为输入,解决输入端大量的小文件场景

2. Map 阶段

  1. 减少溢写( spill )次数: 通过调整 io.sort.mb 及 sort.spill.percent 参数值,增大触发 spill 的内存上限,减少 spill 次数,从而减少磁盘 I / O 。
  2. 减少合并( merge )次数: 通过调整 io.sort. factor 参数,增大 merge 的文件数目,减少 merge 的次数,从而缩短 MR 处理时间。
  3. 在 Map 之后,不影响业务逻辑前提下,先进行 combine 处理,减少 I / O 上面提到的那些属性参数,都是位于 marred-default.xml 文件中,这些属性参数的调优方式如表所示。
属性名称类型默认值说明
mapreduce.task.io.sort.mbint100配置排序map输出时使用的内存缓冲区的大小,默认100MB,实际开发中可以设置大一些
mapreduce.map.sort.spill.percentfloat0.80map输出内存缓冲和用来开始磁盘溢出写过程的记录边界索引的阈值,即最大使用环形缓冲内存的阈值。一般默认是80%。也可以直接设置为100%
mapreduce.task.io.sort.factorint10排序文件时,一次最多合并的流数,实际开发中可将这个值设置为100
mapreduce.task.min.num.spills.for.combineint3运行 Combiner 时,所需的最少溢出文件数(如果已指定 Combiner)

3. Reduce 阶段

  1. 合理设置 Map 和 Reduce 数: 两个都不能设置太少,也不能设置太多。
    太少,会导致 task 等待,延长处理时间;太多,会导致 Map 和 Reduce 任务间竞争资源,造成处理超时等错误。
  2. 设置 Map 和 Reduce 共存: 调整 slowstart.completedmaps 参数,使 Map 运行到定程度后, Reduce 也开始运行,减少 Reduce 的等待时间。
  3. 规避使用 Reduce : 因为 Reduce 在用于连接数据集的时候将会产生大量的网络消耗。
    通过将 MapReduce 参数 setNumReduceTasks 设置为 0 来创建一个只有 Map 的作业
  4. 合理设置 Reduce 端的 buffer : 默认情况下,数据达到一个國值的时候, buffer 中的数据就会写人磁盘,然后 Reduce 会从磁盘中获得所有的数据。
    也就是说, buffer 和 Reduce 是没有直接关联的,中间多一个写磁盘→读磁盘的过程,既然有这个弊端,那么就可以通过参数来配置,使得 buffer 中的一部分数据可以直接输送到 Reduce ,从而减少 I / O 开销。
    这样一来,设置 buffer 需要内存,读取数据需要内存, Reduce 计算也要内存,所以要根据作业的运行情况进行调整。

上面提到的属性参数,都是位于 mapped-default.xml 文件中,这些属性参数的调优方式如表所示。

属性名称类型默认值说明
mapreduce.job.reduce.slowstart.completedmapsfloat0.05当 map task 在执行到5%时,就开始为 reduce申请资源,开始执行 reduce操作, reduce可以开始复制map结果数据和做 reduce shuffle操作
mapred.job.reduce.input.buffer.percentfloat0.0在 reduce过程,内存中保存map输出的空间占整个堆空间的比例。如果 reducer 需要的内存较少,可以增加这个值来最小化访问磁盘的次数

4. Shuffle 阶段

Shuffle 阶段的调优就是给 Shuffle 过程尽量多地提供内存空间,以防止出现内存溢出现象,可以由参数 mapped.child.java.opts 来设置,任务节点上的内存大小应尽量大。

上面提到的属性参数,都是位于 mapred-site.xml 文件中,这些属性参数的调优方式如表所示。

属性名称类型默认值说明
mapped.map.child.java.optsint-Xmx200m当用户在不设置该值情况下,会以最大1GB jvm heap size 启动 map task,有可能导致内存溢出,所以最简单的做法就是设大参数,一般设置为-Xmx1024m
mapred.reduce.child.java.optsint-Xmx200m当用户在不设置该值情况下,会以最大1 GB jvm heap size启动 Reduce task,也有可能导致内存溢出,所以最简单的做法就是设大参数,一般设置为-Xmx1024m

5. 其他调优属性

除此之外, Mapreduce还有一些基本的资源属性的配置,这些配置的相关参数都位于 mapred-default.xml 文件中,可以合理配置这些属性提高 Mapreduce性能,下表列举了部分调优属性。

属性名称类型默认值说明
mapreduce.map.memory.mbint1024一个 Map Task 可使用的资源上限。如果 Map Task 实际使用的资源量超过该值,则会被强制杀死
mapreduce.reduce.memory.mbint1024一个 Reduce Task可使用的资源上限。如果 Reduce Task实际使用的资源量超过该值,则会被强制杀死
mapreduce.map.cpu.vcoresint1每个 Map Task可使用的最多 cpu core数目
mapreduce.reduce.cpu.vcoresint1每个 Reduce Task可使用的最多 cpu core数目
mapreduce.reduce.shuffle.parallelcopiesint5每个 reduce 去map中拿数据的并行数
mapreduce.map.maxattemptsint4每个 Map Task最大重试次数,一旦重试参数超过该值,则认为 Map Task运行失败
mapreduce.reduce.maxattemptsint4每个 Reduce Task最大重试次数,一旦重试参数超过 Int 该值,则认为 Reduce Task运行失败

版权声明:本文为Shockang原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。