根据 MapReduce 运行全流程,对每个环节进行调优
MapReduce 运行流程图
MapReduce 运行流程关键环节及相关参数
- 文件输入:对文件进行切片,可设置切片大小,可设置是否合并小文件
- Map:Map 数量 = 输入文件切片数量
- Map 文件输出:是否合并设置,合并为多大,什么情况下会合并
- Reduce: hive 自动计算 reduce 个数 或者 显式指定 reduce 个数
- Reduce 文件输出:是否合并,合并为多大,什么情况下合并
- 最终文件压缩:job 之间 文件输出是否压缩,HiveSql 执行完毕的最终结果是否合并。
文件输入阶段
切片大小设置
mapreduce.input.fileinputformat.split.minsize=1 默认值为1
mapreduce.input.fileinputformat.split.maxsize=Long.MAXValue 默认值Long.MAXValue因此,默认情况下,切片大小=blocksize
- Split 切片:是 MapReduce 的最小计算单元,计算公式:computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))。因此默认与 HDFS 的 block 保持一致。
- maxsize(切片最大值): 参数如果调到比 blocksize 小,则会让切片变小,而且就等于配置的这个参数的值。
- minsize(切片最小值): 参数调的比 blockSize 大,则可以让切片变得比 blocksize 还大。
- 注意,==MapReduce 的切片是基于文件进行切片,不是切分数据集整体,也不是切分 block==。
示例:
--设置maxsize大小为10M,也就是说一个block的大小为10M
set mapreduce.input.fileinputformat.split.maxsize=10485760;
小文件合并
(Hive 默认就是合并的)
注意,==MapReduce 的切片是基于文件进行切片,不是切分数据集整体,也不是切分 block==。所以,如果有好多小文件,且不开启合并小文件的功能,一个小文件就会对应一个 MapTask,这是非常不划算的。(具体参考本文档上面 MapReduce 框架原理。非常好的博文 )
# hive 的默认值就是这个,不用特别设置
set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
Map
Map 个数:输入文件切片的个数就是 Map 个数,跟 输入文件集合的 文件个数、文件大小有关系。
如何控制:通过设置 split(切片) 大小、合并小文件,控制 Map 的个数。
Map 不是越多越好:大量小文件,如果每个小文件一个 Map,是集群资源的浪费。
Map 也不是越少越好:如果一个 127 M 文件,但是只有 2 个字段,一共有几百万行、几千万行数据,且数据处理逻辑还挺复杂,那么一个 Map 明显就有点少了。
Map 输出文件
合并 map 阶段和 reduce 阶段输出的小文件
我们知道文件数目小,容易在文件存储端造成瓶颈,给 HDFS 带来压力,影响处理效率。对此,可以通过合并 Map 和 Reduce 的结果文件来消除这样的影响。
用于设置合并属性的参数有:
# 是否合并Map输出文件,默认值为真
hive.merge.mapfiles=true
# 是否合并Reduce 端输出文件,默认值为假:
hive.merge.mapredfiles=false
# 合并文件的大小,默认值为 256000000:
hive.merge.size.per.task=256*1000*1000()
更多参数:
作用:当 map 端 或者 reduce 端 输出的平均文件大小小于我们设定的这个值时,就开启合并,将文件合并成一个大文件。
如果 map 端文件合并开关开启了,就合并,否则不合并
如果 reduce 端文件合并开关开启了,就合并,否则不合并
<property>
<name>hive.merge.smallfiles.avgsize</name>
<value>16000000</value>
<description>
When the average output file size of a job is less than this number, Hive will start an additional
map-reduce job to merge the output files into bigger files. This is only done for map-only jobs if hive.merge.mapfiles is true, and for map-reduce jobs if hive.merge.mapredfiles is true.
</description>
</property>
Reduce
根据配置自动计算
1)每个 Reduce 处理的数据量默认是 256MB