`

hadoop各种输入方法(InputFormat)汇总

 
阅读更多

引自http://www.blogjava.net/shenh062326/archive/2012/07/03/hadoop.html

mapreduce , 一个 job map 个数 , 每个 map 处理的数据量是如何决定的呢 ? 另外每个 map 又是如何读取输入文件的内容呢 ? 用户是否可以自己决定输入方式 , 决定 map 个数呢 ? 这篇文章将详细讲述 hadoop 中各种 InputFormat 的功能和如何编写自定义的InputFormat.

 

简介 : mapreduce 作业会根据输入目录产生多个 map 任务 , 通过多个 map 任务并行执行来提高作业运行速度 , 但如果 map 数量过少 , 并行量低 , 作业执行慢 , 如果 map 数过多 , 资源有限 , 也会增加调度开销 . 因此 , 根据输入产生合理的 map , 为每个 map 分配合适的数据量 , 能有效的提升资源利用率 , 并使作业运行速度加快 .

    mapreduce , 每个作业都会通过 InputFormat 来决定 map 数量 . InputFormat 是一个接口, 提供两个方法:

InputSplit[] getSplits(JobConf job, int numSplits) throws IOException;

RecordReader<K, V> getRecordReader(InputSplit split,

                                     JobConf job,

                                     Reporter reporter) throws IOException;

    其中 getSplits 方法会根据输入目录产生 InputSplit 数组 , 每个 InputSplit 会相应产生一个 map 任务 , map 的输入定义在 InputSplit . getRecordReader 方法返回一个 RecordReader 对象 , RecordReader 决定了 map 任务如何读取输入数据 , 例如一行一行的读取还是一个字节一个字节的读取 , 等等 .

    下图是 InputFormat 的实现类:

       (暂时无法上传)

    这理详细介绍 FileInputFormat CombineFileInputFormat, 其它不常用 , 有兴趣的可以自己查看 hadoop 源码 .


 

FileInputFormat( 旧接口 org.apache.hadoop.mapred )

 

 

mapreduce 默认使用 TextInputFormat TextInputFormat 没有实现自己的 getSplits 方法 , 继承于 FileInputFormat, 因此使用了 FileInputFormat的.

org.apache.hadoop.mapred. FileInputFormat getSplits 流程 :

两个配置

mapred.min.split.size         ( 一个 map 最小输入长度 ),

mapred.map.tasks                 ( 推荐 map 数量 )

如何决定每个 map 输入长度呢 ? 首先获取输入目录下所有文件的长度和 , 除以 mapred.map.tasks 得到一个推荐长度 goalSize, 然后通过式子 : Math.max (minSize, Math.min (goalSize, blockSize)) 决定 map 输入长度 . 这里的 minSize mapred.min.split.size, blockSize 为相应文件的 block 长度 . 这式子能保证一个 map 的输入至少大于 mapred.min.split.size, 对于推荐的 map 长度 , 只有它的长度小于 blockSize 且大于 mapred.min.split.size 才会有效果 . 由于 mapred.min.split.size 默认长度为 1, 因此通常情况下只要小于 blockSize 就有效果 , 否则使用 blockSize 做为 map 输入长度 .

因此 , 如果想增加 map , 可以把 mapred.min.split.size 调小 ( 其实默认值即可 ), 另外还需要把 mapred.map.tasks 设置大.

如果需要减少 map , 可以把 mapred.min.split.size 调大 , 另外把 mapred.map.tasks 调小 .

这里要特别指出的是 FileInputFormat 会让每个输入文件至少产生一个 map 任务 , 因此如果你的输入目录下有许多文件 , 而每个文件都很小 , 例如几十 kb, 那么每个文件都产生一个 map 会增加调度开销 . 作业变慢 .

那么如何防止这种问题呢 ? CombineFileInputFormat 能有效的减少 map 数量 .


FileInputFormat( 新接口 org.apache.hadoop.mapreduce.lib.input )

Hadoop 0.20 开始定义了一套新的 mapreduce 编程接口 , 使用新的 FileInputFormat, 它与旧接口下的 FileInputFormat 主要区别在于 , 它不再使用 mapred.map.tasks, 而使用 mapred.max.split.size 参数代替 goalSize, 通过 Math.max (minSize, Math.min (maxSize, blockSize)) 决定 map 输入长度 , 一个 map 的输入要大于 minSize, 小于

Math.min (maxSize, blockSize).

    若需增加 map , 可以把 mapred.min.split.size 调小 , mapred.max.split.size 调大 . 若需减少 map , 可以把 mapred.min.split.size 调大 , 并把 mapred.max.split.size 调小 .

 

CombineFileInputFormat

顾名思义 , CombineFileInputFormat 的作用是把许多文件合并作为一个 map 的输入 .

在它之前 , 可以使用 MultiFileInputFormat , 不过其功能太简单 , 以文件为单位,一个文件至多分给一个 map处理 , 如果某个目录下有许多小文件 , 另外还有一个超大文件 , 处理大文件的 map会严重偏慢 .

CombineFileInputFormat 是一个被推荐使用的 InputFormat. 它有三个配置 :

mapred.min.split.size.per.node 一个节点上 split 的至少的大小

mapred.min.split.size.per.rack   一个交换机下 split 至少的大小

mapred.max.split.size             一个 split 最大的大小

它的主要思路是把输入目录下的大文件分成多个 map 的输入 , 并合并小文件 , 做为一个 map 的输入 . 具体的原理是下述三步 :

1. 根据输入目录下的每个文件 , 如果其长度超过 mapred.max.split.size, block 为单位分成多个 split( 一个 split 是一个 map 的输入 ), 每个 split 的长度都大于 mapred.max.split.size, 因为以 block 为单位 , 因此也会大于 blockSize, 此文件剩下的长度如果大于 mapred.min.split.size.per.node, 则生成一个 split, 否则先暂时保留 .

2. 现在剩下的都是一些长度效短的碎片 , 把每个 rack 下碎片合并 , 只要长度超过 mapred.max.split.size 就合并成一个 split, 最后如果剩下的碎片比 mapred.min.split.size.per.rack , 就合并成一个 split, 否则暂时保留 .

3. 把不同 rack 下的碎片合并 , 只要长度超过 mapred.max.split.size 就合并成一个 split, 剩下的碎片无论长度 , 合并成一个 split.

举例 : mapred.max.split.size=1000

     mapred.min.split.size.per.node=300

      mapred.min.split.size.per.rack=100

输入目录下五个文件 ,rack1 下三个文件 , 长度为 2050,1499,10, rack2 下两个文件 , 长度为 1010,80. 另外 blockSize 500.

经过第一步 , 生成五个 split: 1000,1000,1000,499,1000. 剩下的碎片为 rack1 :50,10; rack2 10:80

由于两个 rack 下的碎片和都不超过 100, 所以经过第二步 , split 和碎片都没有变化 .

第三步 , 合并四个碎片成一个 split, 长度为 150.

 

如果要减少 map 数量 , 可以调大 mapred.max.split.size, 否则调小即可 .

其特点是 : 一个块至多作为一个 map 的输入,一个文件可能有多个块,一个文件可能因为块多分给做为不同 map 的输入, 一个 map 可能处理多个块,可能处理多个文件。


 

 

编写自己的 InputFormat

 

    待续

分享到:
评论

相关推荐

    Hadoop入门程序java源码

    9. `InputFormat`和`OutputFormat`:定义输入数据的分割方式和输出数据的格式。 10. `TextInputFormat`和`TextOutputFormat`:Hadoop默认的文本输入和输出格式。 在源码中,你可能会看到如何定义Mapper和Reducer类...

    Hadoop源代码分析

    3. **InputFormat与OutputFormat**:InputFormat负责将原始输入数据分割成RecordReader可以处理的块,而OutputFormat则定义如何将Reducer的输出写入到最终的文件系统。用户可以通过自定义InputFormat和OutputFormat...

    hadoop 入门

    【Hadoop 入门】 Hadoop 是一个由Apache基金会开发的开源分布式计算框架,它以其高效、可扩展和容错性著称,是大数据处理领域的重要工具。本篇将从Hadoop的基本流程、应用开发以及集群配置和使用技巧三个方面进行...

    hadoop的JAVA编程包

    - **Hadoop Common**:包含各种通用工具和库,如网络通信、配置管理等。 3. **Hadoop的开发环境设置** - **安装Hadoop**:在本地或集群上安装Hadoop,配置环境变量,确保`HADOOP_HOME`指向正确路径。 - **构建...

    Hadoop海量文本处理1

    - **map 方法**:该方法接收一个键值对作为输入,对文本进行正则匹配。如果文本匹配成功,则将键值对输出到 OutputCollector。 2. **main 方法** - **配置 JobConf**:创建了一个 JobConf 实例,并设置了一些必要...

    hadoop api及Hadoop结构与设计

    Hadoop是大数据处理领域的重要工具,其核心组件包括HDFS(Hadoop Distributed File System)和MapReduce...通过熟练掌握Hadoop API和理解其结构设计,开发者能够有效地利用Hadoop进行大数据处理,解决各种业务挑战。

    hadoop文档

    2. **数据输入与输出**:Hadoop程序可以处理各种类型的数据,包括文本、序列化对象、XML等。数据输入通过InputFormat类进行定制,输出则通过OutputFormat类来控制。 3. **数据分片与分区**:MapReduce会根据数据的...

    Hadoop CountWord 例子

    3. **编写Reducer类**:在reduce()方法中,汇总Mapper阶段产生的键值对。 4. **创建OutputFormat**:定义输出数据的格式,如文本文件,其中包含每个单词及其出现次数。 5. **配置Job**:设置作业的参数,如输入和...

    Hadoop源码分析(client部分)

    1. **定义输入格式**:通常使用`TextInputFormat`或自定义的`InputFormat`。 2. **编写Map函数**:处理输入数据,产生中间键值对。 3. **编写Reduce函数**:处理中间键值对,产生最终结果。 4. **定义输出格式**:...

    Hadoop权威指南

    - **Hadoop I/O框架**:提供了一组API和工具,使得开发者可以方便地处理Hadoop中的数据输入和输出操作。 - **MapReduce应用程序开发**:主要包括编写Mapper和Reducer类,以及设置作业参数等步骤。开发者需要关注数据...

    Hadoop.MapReduce.分析

    - **InputFormat**: 负责定义如何将输入数据切分成逻辑片段(InputSplit),以及如何读取这些片段。常见的InputFormat包括`TextInputFormat`、`SequenceFileInputFormat`等。 - **InputSplit**: 表示输入数据的一个...

    细细品味Hadoop_Hadoop集群(第11期副刊)_HBase之旅.pdf

    Mapper类负责将输入数据转换成键值对,Reducer类则负责汇总处理后的结果。 - **HBase InputFormat**:为了从HBase中读取数据,需要使用专门的InputFormat类,如`TableInputFormat`。这种格式允许MapReduce作业直接...

    Java操作Hadoop Mapreduce基本实践源码

    在大数据处理领域,Hadoop MapReduce是一个至关重要的组件,它为海量数据的并行处理提供了分布式计算框架。本文将深入探讨如何使用...通过深入学习和实践,开发者可以利用Hadoop MapReduce解决大数据处理中的各种问题。

    Hadoop运行原理分析

    - 每个MapTask从InputFormat读取输入数据,并使用Map函数处理这些数据,产生一系列中间键值对。 - 中间结果被分区并排序,准备传递给Reduce阶段。 4. **Shuffle阶段**: - 在Map阶段完成后,数据会被重新分布到...

    大数据技术分享 Hadoop运行原理分析 共3页.pdf

    3. **定义InputFormat和OutputFormat**(可选):InputFormat用于将输入文件的内容转换为Mapper可以处理的形式;OutputFormat则负责将Reducer的结果输出到文件系统中。 4. **定义main函数**:在main函数中,开发者...

    Hadoop-2.8.0-Day04-MapReduce编程案例-课件与资料.zip

    2. 数据输入与输出格式:了解InputFormat和OutputFormat接口,以及自定义输入输出格式的必要性。 3. 键值对处理:深入理解Writable接口,如何实现自定义的键值对类。 4. Shuffle与Sort过程:MapReduce如何自动进行...

    Hadoop MapReduce Cookbook

    - **InputFormat & OutputFormat**:指定输入输出数据的格式。 - **Partitioner**:控制map输出如何被分发到reduce任务。 - **Combiner**:可选组件,用于减少网络传输量,可以在map端先做局部汇总。 #### 三、...

    分布式计算利器_MapReduce

    在Hadoop中,一个常见的InputFormat实现是TextInputFormat,它会将输入数据划分为行,每行是一个键值对,键是行的偏移量,值是行的内容。常见的OutputFormat实现是TextOutputFormat,它用于输出文本文件,并以制表符...

    Map-Reduce:Hadoop MR 程序

    此外,Hadoop的`InputFormat`和`OutputFormat`接口用于指定输入数据的格式和输出数据的格式,使得MapReduce程序能够处理各种不同类型的数据源。 在实际应用中,Hadoop MapReduce通常与Hadoop Distributed File ...

    MapReduceV2笔记

    例如,在订单分类统计案例中,需要理解map阶段如何处理输入数据并输出中间键值对,在reduce阶段如何对这些键值对进行汇总和输出最终结果。在二次排序案例中,需要掌握二次排序的原理和实现方法,以及如何优化排序...

Global site tag (gtag.js) - Google Analytics