参考文章:
https://447214075.iteye.com/blog/2153694
2.Hive中如何确定map数 源码级别
文章揭示了不同 InputFormat 下的划分标准
https://blog.csdn.net/wuliusir/article/details/45010129
Hive 中 Mapper 与 Reducer 的个数可以进行指定。但不是简单的通过设置 一个参数值就可以的,下面我们看一下如何设置。
首先,我们看一下一些相关的概念。
为了方便介绍,先来看几个名词:
block_size : hdfs的文件块大小,默认为64M,可以通过参数dfs.block.size设置
total_size : 输入文件整体的大小
input_file_num : 输入文件的个数
Mapper 篇
默认的 mapper 数量
默认的 mapper 数量 跟 文件大小 与 hdfs文件块 大小相关。
default_num = total_size / block_size;
期望Mapper 数量 (生效有条件,一般不这么指定)
可以通过参数 mapred.map.tasks来设置程序员期望的map个数,但是这个个数只有在大于default_num的时候,才会生效。
命令:
set mapred.map.tasks=goal_num;
设置处理的文件大小 (通常通过该种方式进行设置)
- mapper数量计算公式
一个分片对应一个mapper
splitSize = max{minSize,min{maxSize,blockSize}}
maxSize = mapred.max.split.size
minSize = max{mapreduce.input.fileinputformat.split.minsize, mapred.min.split.size}
可以通过mapred.max.split.size 设置每个task处理的文件大小,但是这个大小只有在大于 block_size的时候才会生效。
split_size = max( mapred.min.split.size, block_size);
split_num = total_size / split_size;
命令:
set mapred.max.split.size=goal_num;
mapper 个数的最终计算公式
compute_map_num = min(split_num, max(default_num, goal_num))
除了这些配置以外,mapreduce还要遵循一些原则。 mapreduce的每一个map处理的数据是不能跨越文件的,也就是说max_map_num <= input_file_num。
所以,最终的map个数应该为: final_map_num = min(compute_map_num, input_file_num)
优化:
经过以上的分析,在设置map个数的时候,可以简单的总结为以下几点:
1.减少mapper 数量:
如果想减小map个数,则设置mapred.min.split.size 为一个较大的值。
2.增大mapper 数量:
如果想增加map个数,则设置mapred.map.tasks 为一个较大的值。
Reducer 篇
Reducer 个数:
reducer 相对于 mapper 来说可以直接指定,可以通过如下值进行设定:
mapred.reduce.tasks: 直接指定reducer数量
如 set mapred.reduce.tasks = 10
除此之外,我们还可以指定每个reducer 处理的最大数量 :
hive.exec.reducers.bytes.per.reducer:指定每个reducer处理的数据量
如 set hive.exec.reducers.bytes.per.reducer = 500000000
(500M)
当 总数据量 / 每个Reducer 最大数据量 > Reducer 数量,会对Reducer 进行排队。
扩展篇
除了调整 map , reducer 之外,还有以下几个点需要注意:
1. 设置输入小文件合并,减少 mapper 数量 :
hive有关的MapReduce大作业的性能问题(mapper数过多)
https://blog.csdn.net/qq_31598113/article/details/83018001
hive-site.xml中有几个与合并小文件有关的参数。
hive.merge.mapfiles :是否开启合并 Map 端小文件,true是打开
hive.merge.mapredfiles :是否开启合并 Map/Reduce 小文件,true是打开
hive.hadoop.supports.splittable.combineinputformat :是否支持可切分的CombieInputFormat ,true是支持