mapreduce的InputFormat
1. InputFormat详解
- InputFormat是mapreduce当中用于处理数据输入的一个组件,是最顶级的一个抽象父类,主要用于解决各个地方的数据源的数据输入问题。
2. FileInputFormat常用类
- FileInputFormat类也是InputFormat的一个子类,通过FileInputFormat类来实现操作hdfs上面的文件。我们可以通过FileInputFormat来实现各种格式的文件操作,FileInputFormat的子实现类的UML类图如下
类名 | 主要作用 |
TextInputFormat | 读取文本文件 |
CombineFileInputFormat | 在MR当中用于合并小文件,将多个小文件合并之后只需要启动一个mapTask进行运行 |
SequenceFileInputFormat | 处理SequenceFile这种格式的数据 |
KeyValueTextInputFormat | 通过手动指定分隔符,将每一条数据解析成为key,value对类型 |
NLineInputFormat | 指定数据的行数作为一个切片 |
FixedLengthInputFormat | 从文件中读取固定宽度的二进制记录 |
3. 使用CombineTextInputFormat实现切片个数控制
- 框架默认的TextInputFormat切片机制是对任务按文件规划切片,不管文件多小,都会是一个单独的切片,都会交给一个MapTask,这样如果有大量小文件,就会产生大量的MapTask,处理效率极其低下。
1、应用场景:
CombineTextInputFormat用于小文件过多的场景,它可以将多个小文件从逻辑上规划到一个切片中,这样,多个小文件就可以交给一个MapTask处理。
2、虚拟存储切片最大值设置
CombineTextInputFormat.setMaxInputSplitSize(job, 4194304);// 4m
注意:虚拟存储切片最大值设置最好根据实际的小文件大小情况来设置具体的值。
3、切片机制
生成切片过程包括:虚拟存储过程和切片过程二部分。
- (1) 虚拟存储过程:
将输入目录下所有文件按照文件名称字典顺序排序,将每个文件的大小,依次和设置的setMaxInputSplitSize值比较;
①如果不大于设置的最大值,逻辑上划分一个块;②如果输入文件大于最大值,小于最大值的2倍,那么会将文件平分为2个虚拟存储块;③如果输入文件大于最大值的两倍,那么以最大值为单位切割出虚拟存储块;当剩余数据大小大于设置的最大值,且小于等于最大值2倍时,此时将剩余数据均分成2个虚拟存储块(防止出现太小切片)。
例如setMaxInputSplitSize值为4M,输入文件大小为8.02M,则先逻辑上分成一个4M。剩余的大小为4.02M,如果按照4M逻辑划分,就会出现0.02M的小的虚拟存储文件,所以将剩余的4.02M文件切分成(2.01M和2.01M)两个虚拟存储文件。
- (2)切片过程:
(a)判断虚拟存储的文件大小是否大于setMaxInputSplitSize值,大于等于则单独形成一个切片。
(b)如果不大于则跟下一个虚拟存储文件进行合并;如果合并后,还不大于setMaxInputSplitSize,则继续与下一个虚拟存储文件进行合并;当合并后,大于setMaxInputSplitSize后,共同形成一个切片。
(c)测试举例:有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