第一步:
1.当输入文件超过mapred.max.split.size大小时,以Math.max(minSize,Math,min(maxSize,blockSize))为单位(以他的倍数)切分成不大于mapred.max.split.size大小的split分片。其余的生成碎片文件如果大于nodeSize就生成split,否则待处理
2.当输入文件小于mapred.min.split.size大小时,进行合并文件生产split分片,但是合并的当前文件要小于maxSize。其余的生成碎片文件如果大于nodeSize就生成split,否则待处理
第二步:
1.合并同一个节点的碎片,合成条件满足不小于nodeSize(mapred.min.split.size.per.node)
2.合并同一个机架的碎片,合成条件满足不小于rackSize(mapred.min.split.size.per.rack)
3.合并不同机架的碎片,合成条件只要长度超过mapred.max.split.size就合并成一个split, 剩下的碎片无论长度, 合并成一个split
备注:如果设置mapred.combine.input.format.local.only=false时,在切分完之后,发现split小于maxSize时,就进行合并,并且是挂节点和挂机架的合并,这个要慎用

**例题1:**输入目录下五个文件,rack1下三个文件,长度为2050,1499,10, rack2下两个文件,长度为1010,80. 另外blockSize为500.
mapred.max.split.size=1000
mapred.min.split.size.per.node=300
mapred.min.split.size.per.rack=100
第一步:
rack1 split:1000 1000 1000 499 碎片:50 10
rack2 split: 1000 碎片:10 80
第二步:
rack1 split:1000 1000 1000 499 碎片:50+10
rack2 split: 1000 碎片:10+80
第三步:
rack1 split:1000 1000 1000 499
rack2 split: 1000
碎片(50+10)+(10+80)=150

以上例题是理想情况下,一般的话可能出现同一个文件在不同节点上出现,所以我们通过这种方式是计算的大概。
所以:
以上例题是理想情况下,一般的话可能出现同一个文件在不同节点上出现,所以我们通过这种方式是计算的大概。
所以:
增加map task数量时:
要尽量拆分文件,调小maxSize(如果文件大于maxSize时,就要切分)
要避免合并文件,调小minSize(默认就行,默认大小为1,如果文件小于minSize就要合并文件,而此时文件都不具备合并条件,所以切分出的split数量就多)
减小map task数量时:
要尽量合并文件,适量调大minSize(minSize < maxSize ,如果minSize大于文件时,就具有合并文件,需要合并多大文件还需要看maxSize的大小,当前合并的文件如果超过maxSize就不能合并了,比如文件,a=123,b=423,c=843,maxSize=500,当a,b合并后为546,在合并c时,发现已经大于500了,就不在合并了)
要避免拆分文件,调大maxSize

备注:
maxSize=mapred.max.split.size
minSize=mapred.min.split.size
nodeSize=mapred.min.split.size.per.node
rackSize=mapred.min.split.size.per.rack
设置:
#合并map的输入split文件
hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
dfs.block.size=默认

set mapred.combine.input.format.local.only=false;
这个参数默认为true,是合并同一个节点的数据,当设置为false时,就开启跨节点和跨机架合并文件。合并的文件不大于maxSize,建议不要开启这个参数,因为这样的话会大大消耗磁盘I/O。如果有非常大量的小文件时,可以开启这个参数,比如有200个小文件,都是在10m左右,每个计算逻辑又简单,这时可以开启这个参数。