1.设置Map个数

map个数无法直接设置,只能通过设置切片大小来间接增大或减小map个数

首先需要明白两个参数的含义

mapred.min.split.size:这个参数指定了切片的最小大小,它决定了文件是否需要切片。如果文件大小小于这个值,则不会进行切片。默认值为1字节,但设置过小会导致处理速度变慢。

mapred.max.split.size:这个参数指定了切片的最大大小。当文件大于这个值时,会被分成多个切片。默认值为256MB。

具体分如下两种情况:

1、小文件(1-10M)过多

mapred.min.split.size设置为1M或其他大小,而mapred.max.split.size默认值

此时当大于1M,但小于256M的文件都会被合并,最终合并的大小不超过256M,但需要注意的是,这部分文件会被先切分成1M,再向256M进行合并,这中间的切分其实是有一定开销在里边的,所以我们要保证,文件最好都是这个大小范围,而不是有很多过大的文件或者过小的文件,因为小于1M过多会牺牲掉小文件合并,而单独启动多个map

同时我们在估算map数量时其实还要考虑到一个副本问题:

如果输入文件为多个文件,它有三个副本,每个文件可能来自不同的副本,而不同的副本都存在于不同的节点和机架,即每个节点内的文件可以按照上述规则切分,但由于per.node默认为1,会暂存于block,最后暂存于三个节点的碎片会每个合成一个split,

和我们设想的map个数并不一样,比如,我们现在该目录下游60个大小为3k左右的文件,加一起也就是180k,但最后的map数却是三个,此时如何让多个节点上的文件合并在一起是个问题

在开启了org.apache.hadoop.hive.ql.io.CombineHiveInputFormat后,一个data node节点上多个小文件会进行合并,合并文件数由mapred.max.split.size限制的大小决定。

mapred.min.split.size.per.node决定了多个data node上的文件是否需要合并mapred.min.split.size.per.rack决定了多个交换机上的文件是否需要合并

set mapred.max.split.size=256000000

set mapred.min.split.size.per.node=256000000

set mapred.min.split.size.per.rack=256000000

所以通常我们将这三个参数都设置为同一个值,来达到我们想要的一个map处理的文件大小为256M的需求,即一个节点内文件会朝256M目标合并,如果不到256M,则暂存,不同节点和机架拿着暂存的碎片,继续朝着这个目标合并,使最后的文件大小向256M靠近

2、大文件(100M左右)过多

mapred.min.split.size设置为128M或其他大小,maxsize默认

此时小于128M的文件将不会进行合并,虽然牺牲了小文件合并,但是换来的是防止所有超过1字节(minsize默认1字节)的文件都会被先切分成1字节,再向256M进行合并中间的消耗

3、总结

maxsize是切片的最大限制,作用有2:

1、超过该值的大文件根据该值切片;2、不超过该值的文件,朝该值所设大小合并

minsize是是否要切片的最小限制,作用也有2:

1、超过该值的文件再结合maxsize决定要不要进行合并,合并的时候先将文件切分成该值(极小的切片);2、不超过该值的文件直接不切片也不合并,直接启动一个map

minsize尤其重要,它设置的多与少,取决于大多数文件的大小,你需要找到一个均衡点,既让大多数偏小(这里的偏小偏大没有绝对意义上的大与小,只是相对其他文件的比较)的文件可以参与合并,又让大多数偏大的文件不用先切分的极小,再进行合并

2.设置Reduce个数

reduce个数的计算逻辑没有Map那样复杂,通常可以直接指定个数

set hive.exec.reducers.max=1,

set mapred.reduce.tasks=1

其中mapred.reduce.tasks和hive.exec.reducers.max设置一个即可,前者代表所有任务中的reduce个数,后者代表每个任务也就是stage的最大个数,当底层公式计算的个数比该值大时,生效该值,小时生效计算值

但这里无论生效哪个,当reducetask个数设置时,直接以reducetask为准,公式为nvl(reducetask, min(reducemax, min(1009, 程序计算)))

假如我们未设置reducetask,但设置了reducemax为10,此时程序计算出需要2000个reduce,但reduce上限默认是1009个,但reducemax为10,故最终为10个reduce

假如我们未设置reducetask,但设置了reducemax为10,此时程序计算出需要2个reduce,则经过两次取最小值,故最终为2个reduce

但如果我们设置reducetask为5,不管里面是需要10个还是2个reduce,最终都为5个reduce

故如果我们想让reduce个数固定为某个值,则设置mapred.reduce.tasks,如果我们想让个数尽可能小于某个值,则设置hive.exec.reducers.max

3.设置map和reduce输出文件合并大小

map only任务有时候能合并有时候不能合并,原因是hive.merge.smallfiles.avgsize默认值为16M

这是个判断参数,也就是说当输出文件的平均大小小于该值时才会合并,分区表是分区下的文件平均值小于该值合并,

和hive.merge.mapfiles无关,Map端输出合并和reduce端输出合并参数默认就是打开的

比如我们输出的两个文件,一个为11M,一个17M,平均小于16M,则合并,会另外再走一个合并的stage

如果我们输出的两个文件,一个为1M,一个为100M,平均大小大于16M,则不合并,不会走合并的stage

4.其他一些常用设置

设置map和reduce核数(并行度):

set mapreduce.map.cpu.vcores=2

set mapreduce.reduce.cpu.vcores=10

设置map进行到多少时开始reduce:

set mapreduce.job.reduce.slowstart.completedmaps=0.4

相关文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。