在job提交过程中,在submitter.submitJobInternal的方法中,从以下代码进行切片并把切片数作为maps数量
进入writeSpites方法,会调用writeNewSplits方法。在writeNewSplits方法中会调用input。input.getSplits方法进行切片并返回逻辑切片的列表,而createSplitFiles将会在临时工作目录创建切片元数据信息文件。而input则是通过反射创建一个InputFormat对象,默认是TextInputFormat。
继续进入getSplits方法来到TextInputFormat的getSplites方法。分区的重点。或获取TextInputFormat的最小分区数(1),配置文件位置的最小分区数(默认为1)中的较大者,再获取job配置的最大分区数(long的最大值)。在后面将对这三个进行比较赋值操作
随后,会获取指定文件夹下的所有文件生成一个List,然后会使用迭代器依次对这些文件进行分区:
下面是分区的核心代码。对文件夹下的文件一个个进行分片,如果文件不支持分片,则整个文件作为一个分片,否则调用computeSplitSize方法计算分片大小,用到了上面的那几个参数,有源码可知先取块大小和最大分片数的较小者,在本地模式下块大小是32m,而yarn模式是128m,显然如果不设置job最大分片数,blocksize将是较小者。然后和最小分区数相比取较大的一个,由于miniSize是job配置的最小分区数和1之间的最大者,显然miniSize由配置的job最小分区数决定,因此:
- 不加配置的情况下分片大小是blocksize,32m或者128m
- 配置了job最大分片数在132m或1128m,而没有配置job最小分片数时,分片数就是配置的job最大分片数
- 配置了job最大分片数大于32m(本地模式)或者128m(Yarn模式)时,就不起作用了,由block决定,此时如果配置的最小job分区数大于blocksize,则是配置的值,否则是blocksize的值
- 配置的最小job分片数如果小于blocksize,那么无论如何都不起作用。
计算完分片数后,会通过for循环不断对单个文件进行分片,首先会计算文件剩余未分配部分和分片大小spliteSize的比值,如果比值大于1.1,则会把剩下分文件分成一个片,否则就会把剩下的文件单独分成一个片。(比如剩下32.1m,则会把32.1m单独分成一个片),在记录好分片的起始位置和结束位置后返回一个分片列表,至此分片结束。(切片完成后会调用方法在提交job工作目录创建分片信息文件。)