hadoop自定义输入格式
一个任务的开始阶段是由InputFormat来决定的!
1.在MapReduce框架中,InputFormat扮演的角色:
– 将输入数据切分成逻辑的分片(Split),一个分片将被分配给一个单独的Mapper
– 提供RecordReader的对象,该对象会从分片中读出<Key-Value>对供Mapper
处理
1.1InputFormat对Mapper的影响:
– 决定了Mapper的数量
– 决定了Mapper的map函数接收的Key和Value
1.2InputFormat:
InputFormat源码解释:
InputFormat是一个抽象类,定义了两个方法,getSplits()将输入数据切割成分片,返回类型为切片集合List<inputSplit>的集合和createRecordReader()用来读取一条一条的<k,v>给map的run方法
具体来说:
getSplits负责将输入数据进行划分,生成一组分片
createRecordReader返回的对象,负责从分片中读取<Key-Value>对
1.3InputSplit源码解释:
InputSplit也是一个抽象类,所有分片类型都是它的子类,分片的类都继承自它,也定义了两个方法
方法getLength()用于获取分片的大小
方法getLocations()用于获取存储分片的位置列表
2.MapReduce调用RecordReader
调用Mapper类,实际上就是调用它的run函数,Mapper通过context来获取Key-Value对,而context的nextKeyValue、
getCurrentKey、getCurrentKey方法,就是调用InputFormat返回的RecordReader对象
3.InputFormat:类层次结构
3.1FileInputFormat:
FileInputFormat是InputFormat的子类,所有使用文件为数据源的输入格式类都继承
自它
---实现了getSplits方法
---返回的分片类型是FileSplit(private Path file),是InputSplit的子类,里面加入了描述文件路径,分片开始位置
的信息
---没有实现createRecordReader方法,是一个抽象类
FileInputFormat:生成分片
默认情况下为文件在HDFS上的每一个block都生成一个分片
---可通过作业的配置参数mapred.min.split.size和mapred.max.split.size来设置分片大
小的最小值和最大值,设置这两个参数后,可能会对文件连续的block生成一个分片,
使分片大小在指定的范围内。
---一个分片包含的block只来自一个文件
4. MapReduce默认的输入格式是:TextInputformat
TextInputFormat
TextInputFormat 是默认的输入格式
是FileInputFormat的子类,继承了它的getSplit方法,也就是说它的分片逻辑同样是指分片只包含一个文件的内容,如果输入文件有上万个,那么就会产生上万个分片,进而需要调用至少上万个Mapper!实验证明,对3000多个文本文件进行分词操作,会产生3000多个mapper,所花费时间3.5h
createRecordReader返回的是lineRecordReader的对象
– 每行数据生成一条<Key, Value>记录
– Key:每个数据的记录在数据分片中字节偏移量,类型是LongWritable
– Value:每行的内容,类型是Text
4.1自定义输入格式,来解决小文件问题:
Mapper输入的每一条记录代表一个文件
---Mapper处理后的结果可以直接输出,不
需要再经过Reducer的处理
---解决Hadoop处理大量小文件的问题
CombineFileInputFormat
CombineFileInputFormat是针对小文件设计的输入格式
继承了类FileInputFormat
重写了getSplit方法
–- 返回的分片类型是CombineFileSplit(private Path[] paths用来记录每一个文件的路径),是InputSplit的子类
--可包含多个文件的路径(这是两者最大的不同),
是一个抽象类,编写具体类需要实现createRecordReader方法
– 返回值的类型是CombineFileRecordReader,它用于处理类型为CombineFileSplit的分
片
– CombineFileRecordReader的构造函数中,还需指定一个RecordReader,用于处理分片内
的单个文件
CombineFileInputFormat:生成分片
输出的分片中可包含多个不同文件的block
文件切分原理:http://blog.sina.com.cn/s/blog_5673f78b0101etz4.html
自定义输入格式MyInputFormat:
----重写isSplitable方法来确保文件不被分割,每个文件都只分配到一个分片
----一个分片可包含多个文件
----输出的每条<Key, Value>对应一个完整的文本文件
– Key: 文件所属的类别名, 类型是Text
– Value: 文件的文本内容, 类型是Text