了解inputSplit
Hadoop将MapReduce的输入数据划分成等长的小数据块,称为输入分片(input split)或简称为“分片”。Hadoop为每个分片构建一个map任务,并由该任务来运行用户自定义的map函数从而处理分片中的每条数据。
getSplits()负责将文件切分成多个分片(InputSplit),但InputSplit并没有实际切分文件,而只是说明了如何切分数据,也就是说,InputSplit只是逻辑上的切分。createRecordReader()则创建了RecordReader,用来从InputSplit读取记录。
每个InputSplit对应一个map任务。作为map的输入,在逻辑上提供了这个map任务所要处理的key-value对。
Hadoop 2.x默认的block大小是128MB,Hadoop 1.x默认的block大小是64MB,可以在hdfs-site.xml中设置dfs.block.size,注意单位是byte。
我们没有设置分片的范围的时候,分片大小是由block块大小决定的,和它的大小一样。比如把一个258MB的文件上传到HDFS上,假设block块大小是128MB,那么它就会被分成三个block块,与之对应产生三个split,所以最终会产生三个map task。
而最后一个块只是2MB的大小,并不是block的大小128MB,它在文件系统里只占2MB的空间。
分片的大小并不是随意分配的。
拥有许多分片,意味着处理每个分片所需要的时间少于处理整个谁数据所花的时间。因此,如果我们并行处理每个分片,且每个分片数据比较小,那么整个处理过程将获得更好的负载平衡。
如果分片切分得太小,那么管理分片的总时间和构建map任务的总时间将决定作业的整个执行时间。对于大多数作业来说,一个合理的分片大小趋向于HDFS的一个块的大小,默认为64MB,不过可以针对集群调整这个默认值,或对新建的每个文件具体指定。