InputFormat数据输入
一、切片与MapTask并行度决定机制
MapReduce的数据流为:
MapTask的并行度决定Map阶段的任务处理并发度,进而影响到整个Job的处理速度。
InputFormat会在数据提交前对数据进行切片处理。
**数据块:**Block是HDFS物理上把数据分成一块一块。
**数据切片:**数据切片只是在逻辑上对输入进行分片,并不会在磁盘上将其切分成片进行存储。
不同的InputFormat对象会有不同的分片策略,进而导致不同的分片结果,从而影响MapTask的并行度,并决定Map阶段的任务处理并发度。
二、常见切片机制介绍
2.1 FileInputFormat
FileInputFormat 会简单地按照文件的内容长度进行切片,切片大小默认为HDFS设置的数据块的大小。FileInputFormat 进行切片时不会考虑数据集整体,而是逐个针对每一个文件进行切片。
例如:
如果输入有两个文件File1.txt
、File2.txt
,
File1.txt
大小为320M。
File2.txt
大小为10M。
经过FileInputFormat的切片运算后,会生成4片。
file1.txt.sprit1——0~128M
file1.txt.sprit2——128~256M
file1.txt.sprit3——256~320M
file2.txt.sprit1——0~10M
2.2 TextInputFormat
TextInputFormat 是默认的FileInputFormat实现类。实现按行读取每条记录。也是框架默认的切片机制 。TextInputFormat 会对任务按文件规划切片,不管文件多小,都会是一个单独的切片,都会交给一个MapTask,这样如果有大量小文件,就会产生大量的MapTask,导致处理效率极其低下。
传入 Mapper 中的 map 方法的 KEYIN 就是 TextInputFormat 读取行时改行在整个文件中的起时字节偏移量,为LongWritable类型。传入 Mapper 中的 map 方法的 VALUEIN 则是读取的这行的内容(不包括任何换行符和回车符)为Text类型。
2.3 CombineTextInputFormat切片机制
CombineTextInputFormat 一般用于小文件过多的场景,它可以将多个小文件从逻辑上规划到一个切片中,这样,多个小文件就可以交给一个MapTask处理。
可以通过以下代码来设置虚拟存储切片最大值
CombineTextInputFormat.setMaxInputSplitSize(job, 4194304);// 4m
注意:虚拟存储切片最大值设置最好根据实际的小文件大小情况来设置具体的值。
切片机制:
生成切片过程包括:虚拟存储过程和切片过程二部分。
1、虚拟存储过程:
将输入目录下所有文件大小,依次和设置的 setMaxInputSplitSize 值比较,如果不大于设置的最大值,逻辑上划分一个块。如果输入文件大于设置的最大值且大于两倍,那么以最大值切割一块;当剩余数据大小超过设置的最大值且不大于最大值2倍,此时将文件均分成2个虚拟存储块(防止出现太小切片)。
例如 setMaxInputSplitSize 值为4M,输入文件大小为8.02M,则先逻辑上分成一个4M。剩余的大小为4.02M,如果按照4M逻辑划分,就会出现0.02M的小的虚拟存储文件,所以将剩余的4.02M文件切分成(2.01M和2.01M)两个文件。
2、切片过程:
-
判断虚拟存储的文件大小是否大于 setMaxInputSplitSize 值,大于等于则单独形成一个切片。
-
如果不大于则跟下一个虚拟存储文件进行合并,共同形成一个切片。
例:有4个小文件大小分别为1.7M、5.1M、3.4M以及6.8M这四个小文件,则虚拟存储之后形成6个文件块,大小分别为:
1.7M,(2.55M、2.55M),3.4M以及(3.4M、3.4M)
最终会形成3个切片,大小分别为:
(1.7+2.55)M,(2.55+3.4)M,(3.4+3.4)M
及(3.4M、3.4M)
最终会形成3个切片,大小分别为:
(1.7+2.55)M,(2.55+3.4)M,(3.4+3.4)M