飞鸟各投林

导航

Hadoop MapReduce InputFormat基础

有时候你可能想要用不同的方法从input data中读取数据。那么你就需要创建一个自己的InputFormat类。
 
InputFormat是一个只有两个函数的接口
 
1 public interface InputFormat<K, V> {
2     InputSplit[]   getSplits(JobConf job, int numSplits) throws IOException;
3     RecordReader<K, V> getRecordReader(InputSplit split,JobConf job, Reporter reporter) throws IOException;
4 }

 

 getSplits():标记所有的输入数据,然后将他们切分为小的输入数据块,每个Map任务处理一个数据块
 getRecordReader():提供一个RecordReader来从给定的数据块中迭代处理数据,然后将数据处理为<key,value>格式
由于没有人愿意关心怎样将数据块分为小的数据块,你应该继承FileInputFormat类,它用来处理数据的分块。
大部分已知的InputFormat就是FileInputFormat的子类
InputFormatDescription
TextInputFormat 输入文件中的每一行就是一个记录,Key是这一行的byte offset,而value是这一行的内容。
Key: LongWritable
Value: Text
KeyValueTextInputFormat 输入文件中每一行就是一个记录,第一个分隔符字符切分每行。在分隔符字符之前的内容为Key,在之后的 为Value。
分隔符变量通过key.value.separator.in.input.line变量设置,默认为(\t)字符。
Key: Text
Value: Text
SequenceFileInputFormat<K,V> 一个用来读取字符流数据的InputFormat,<Key,Value>为用户自定义的。字符流数据是Hadoop自定义的压缩的二进制数据格式。
它用来优化从一个MapReduce任务的输出到另一个MapReduce任务的输入之间的数据传输过程。
Key: K(用户自定义)
Value: V(用户自定义)
NLineInputFormat 与TextInputFormat一样,但每个数据块必须保证有且只有N行,mapred.line.input.format.linespermap属性,默认为1,设置为N。
Key: LongWritable
value: Text
 
FileInputFormat实现getSplits()方法,但是仍然保留getRecordReader()方法为abstract以使其子类实现。
FileInputFormat的getSplits()实现试着将输入数据分块大小限制在numSplits值之上,numSplits<数据块<hdfs block size 
FileInputFormat有一些子类可以重载的protected函数,例如isSplitable(),它用来确定你是否可以切分一个块,默认返回为true,表示只要数据块大于hdfs block size,那么它将会被切分。但有时候你不希望切分一个文件,例如某些二进制序列文件不能被切分时,你就需要重载该函数使其返回false。 
在用FileInputFormat时,你主要的精力应该集中在数据块分解为记录,并且生成<key,value>键值对的RecordReader方法上。
 
1 public interface RecordReader<K, V> {
2   boolean next(K key, V value) throws IOException;
3   K createKey();
4   V createValue();
5  
6   long getPos() throws IOException;
7   public void close() throws IOException;
8   float getProgress() throws IOException;
9 }

 

 
 
 
 

posted on 2016-04-11 23:27  飞鸟各投林  阅读(288)  评论(0编辑  收藏  举报