天天看点

hadoop inputformat

MapReduce过程Mapper的输出参数和Reducer的输入参数是一样的,都是中间需要处理的结果,而Reducer的输出结果便是我们想要的输出结果。所以根据需要对InputFormat进行较合理的设置,Job才能正常运行。Job过程中间的Key和Value的对应关系可以简单阐述如下:

  • map: <k1,v1> -> list(k2,v2)
  • combile: <k2,list(v2)> -> list(k2,v2)
  • reduce: <k2,list(v2)> -> list(k3,v3)

至于为什么需要显示指定中间、最终的数据类型,貌似看上去很奇怪,原因是Java的泛型机制有很多限制,类型擦出导致运行过程中类型信息并非一直可见,所以Hadoop不得不明确指定。

InputFormat的结构图如下:

hadoop inputformat

还有想说明的是,单个reducer的默认配置对于新手而言很容易上手,但是在真实的应用中,reducer被设置成一个较大的数字,否则作业效率极低。reducer的最大个数与集群中reducer的最大个数有关,集群中reducer的最大个数由节点数与每个节点的reducer数相乘得到。该值在mapred.tasktracker.reduce.tasks.maximum决定

下面介绍一些常用的InputFormat和用法。

**

FileInpuFormat

**

FileInputFormat是所有使用文件作为数据源的InputFormat的积累。它提供两个功能:一个是定义哪些文件包含在一个作业的输入中;一个为输入文件生成分片的实现。自动将作业分块 作业分块大小与mapred-site.xml中的mapred.min.split.size和mapred.min.split.size和blocksize有关系。分片大小由如下公式来决定:

分片大小 = max(minimumSize, min(maximumSize, blockSize))

如果想避免文件被切分,可以采用如下两种之一,不过推荐第二种。

1)设置minimum size 大于文件大小即可

2)使用FileInputFormat子类并重载isSplitable方法返回false

import org.apache.hadoop.fs.*;

import org.apache.hadoop.mapred.TextInputFormat;

public class NonSplittableTextInputFormat extends TextInputFormat {

  @Override

  protected boolean isSplitable(FileSystem fs, Path file) {

    return false;

  }

}

CombileFileInputFormat

CombileFileInputFormat是为了解决大批量的小文件作业。

TextInputFormat

(LongWritable,Text:字节偏移量,每行的内容)

默认的InputFormat。键是改行文件在源文件中的偏移量,值是该行内容(不包括终止符,如换行符或者回车符)。如

On the top of the Crumpetty Tree

The Quangle Wangle sat,

But his face you could not see,

On account of his Beaver Hat.

被表示成键值对如下:

<0, On the top of the Crumpetty Tree>

<33, The Quangle Wangle sat,>

<57, But his face you could not see,>

<89, On account of his Beaver Hat.>

KeyValueTextInputFormat

如果文件中的每一行就是一个键值对,使用某个分界符进行分隔,比如Tab分隔符。例如Hadoop默认的OutputFormat产生的输出,即是每行用Tab分隔符分隔开的键值对。

可以通过key.value.separator.in.input.line属性来指定分隔符,默认的值是一个Tab分隔符。(注: → 代表一个Tab分隔符)

line1→On the top of the Crumpetty Tree

line2→The Quangle Wangle sat,

line3→But his face you could not see,

line4→On account of his Beaver Hat.

被表示成键值对如下:

<line1, On the top of the Crumpetty Tree>

<line2, The Quangle Wangle sat,>

<line3, But his face you could not see,>

<line4, On account of his Beaver Hat.>

NLineInputFormat

以行号来分割数据源文件。N作为输入的行数,可以有mapred.line.input.format.linespermap来指定。

On the top of the Crumpetty Tree

The Quangle Wangle sat,

But his face you could not see,

On account of his Beaver Hat.

如果N是2,则一个mapper会收到前两行键值对:

<0, On the top of the Crumpetty Tree>

<33, The Quangle Wangle sat,>

另一个mapper会收到后两行:

<57, But his face you could not see,>

<89, On account of his Beaver Hat.>

继续阅读