Hadoop中的InputFormat解析
1、InputFormat
InputFormat是Hadoop平台上Mapreduce输入的规范,仅有两个抽象方法。
- List<InputSplit> getSplits(), 获取由输入文件计算出输入分片(InputSplit),解决数据或文件分割成片问题。
 - RecordReader<K,V> createRecordReader(),创建RecordReader,从InputSplit中读取数据,解决读取分片中数据问题。
 
InputFormat主要能完成下列工作:
1、Validate the input-specification of the job. (首先验证作业的输入的正确性)
2、 Split-up the input file(s) into logical InputSplits, each of which is then assigned to an individual Mapper.(将输入的文件划分成一系列逻辑分片 
(InputSplit),一个InputSplit将会被分配给一个独立的MapTask )
3、Provide the RecordReader implementation to be used to glean input records from the logical InputSplit for processing by the Mapper.(提供RecordReader实
现,读取InputSplit中的“K-V对”供Mapper使用)
InputFormat的源代码:
public abstract class InputFormat<K, V> {
  /**
   * 每个InputSplit的分片被分配到一个独立的Mapper上
   * 注:1、这个分片是逻辑上对输入数据进行分片,而实际上输入文件没有被切割成一个个小块。
   *     每个分片由输入文件的路径,起始位置,偏移量等
   *     2、在InputFormat中创建的RecordReader也要使用InputSplit
   */
  public abstract
    List<InputSplit> getSplits(JobContext context ) throws IOException, InterruptedException;
  /**
   * 为每个分片创建一个record reader
   */
  public abstract
    RecordReader<K,V> createRecordReader(InputSplit split,TaskAttemptContext context)
            throws IOException, InterruptedException;
2.InputSplit
Mapper输入的是一个个分片,称InputSplit。在这个抽象类中,是将每个输入分片(Split)中的内容解析成K-V值。
InputSplit的源代码:
public abstract class InputSplit {
  /**
   * 得到每个分片的大小,可以按照分片大小排序。
   */
  public abstract long getLength() throws IOException, InterruptedException;
  /**
   * Get the list of nodes by name where the data for the split would be local.
   * The locations do not need to be serialized.
   * 获取存储该分片的数据所在的节点位置
   */
  public abstract String[] getLocations() throws IOException, InterruptedException;
}
2.1 下面看看InputSplit的一个子类,FileSplit类:
  public FileSplit() {}
   /** Constructs a split with host information
    *
    * @param file the file name
    * @param start the position of the first byte in the file to process
    * @param length the number of bytes in the file to process
    * @param hosts the list of hosts containing the block, possibly null
    */
   public FileSplit(Path file, long start, long length, String[] hosts) {
     this.file = file;
     this.start = start;
     this.length = length;
     this.hosts = hosts;
   }
   /** The file containing this split's data. */
   public Path getPath() { return file; }
   /** The position of the first byte in the file to process. */
   public long getStart() { return start; }
   /** The number of bytes in the file to process. */
   @Override
   public long getLength() { return length; }
   @Override
   public String toString() { return file + ":" + start + "+" + length; }
   ////////////////////////////////////////////
   // Writable methods
   ////////////////////////////////////////////
   @Override
   public void write(DataOutput out) throws IOException {
     Text.writeString(out, file.toString());
     out.writeLong(start);
     out.writeLong(length);
   }
   @Override
   public void readFields(DataInput in) throws IOException {
     file = new Path(Text.readString(in));
     start = in.readLong();
     length = in.readLong();
     hosts = null;
   }
   @Override
   public String[] getLocations() throws IOException {
     if (this.hosts == null) {
       return new String[]{};
     } else {
       return this.hosts;
     }
   } 
从源码中可以看出,FileSplit有四个属性:文件路径,分片起始位置,分片长度和存储分片的hosts。用这四项数据,就可以计算出提供给每个Mapper的分片数据。在InputFormat的getSplit()方法中构造分片,分片的四个属性会通过调用FileSplit的Constructor设置。
2.2再看一个InputSplit的子类:CombineFileSplit。源码如下:
为什么介绍该类呢,因为该类对小文件的处理是很有效的,所有深入理解该类,将有助于该节学习。
上面我们介绍的FileSplit对应的是一个输入文件,也就是说,如果用FileSplit对应的FileInputFormat作为输入格式,那么即使文件特别小,也是作为一个单独的InputSplit来处理,而每一个InputSplit将会由一个独立的Mapper Task来处理。在输入数据是由大量小文件组成的情形下,就会有同样大量的InputSplit,从而需要同样大量的Mapper来处理,大量的Mapper Task创建销毁开销将是巨大的,甚至对集群来说,是灾难性的!
CombineFileSplit是针对小文件的分片,它将一系列小文件封装在一个InputSplit内,这样一个Mapper就可以处理多个小文件。可以有效的降低进程开销。与FileSplit类似,CombineFileSplit同样包含文件路径,分片起始位置,分片大小和分片数据所在的host列表四个属性,只不过这些属性不再是一个值,而是一个列表。
需要注意的一点是,CombineFileSplit的getLength()方法,返回的是这一系列数据的数据的总长度。
现在,我们已深入的了解了InputSplit的概念,看了其源码,知道了其属性。我们知道数据分片是在InputFormat中实现的,接下来,我们就深入InputFormat的一个子类,FileInputFormat看看分片是如何进行的。
3 、FileInputFormat
FileInputFormat中,分片方法代码及详细注释如下,就不再详细解释该方法:
Hadoop中的InputFormat解析的更多相关文章
- Hadoop中Partition深度解析
		
本文地址:http://www.cnblogs.com/archimedes/p/hadoop-partitioner.html,转载请注明源地址. 旧版 API 的 Partitioner 解析 P ...
 - hadoop中InputFormat 接口的设计与实现
		
InputFormat 主要用于描述输入数据的格式, 它提供以下两个功能.❑数据切分:按照某个策略将输入数据切分成若干个 split, 以便确定 Map Task 个数以及对应的 split.❑为 M ...
 - Hadoop中常用的InputFormat、OutputFormat(转)
		
Hadoop中的Map Reduce框架依赖InputFormat提供数据,依赖OutputFormat输出数据,每一个Map Reduce程序都离不开它们.Hadoop提供了一系列InputForm ...
 - Hadoop 中疑问解析
		
Hadoop 中疑问解析 FAQ问题剖析 一.HDFS 文件备份与数据安全性分析1 HDFS 原理分析1.1 Hdfs master/slave模型 hdfs采用的是master/slave模型,一个 ...
 - Hadoop中Yarnrunner里面submit Job以及AM生成 至Job处理过程源码解析
		
参考 http://blog.csdn.net/caodaoxi/article/details/12970993 Hadoop中Yarnrunner里面submit Job以及AM生成 至Job处理 ...
 - hadoop中OutputFormat 接口的设计与实现
		
OutputFormat 主要用于描述输出数据的格式,它能够将用户提供的 key/value 对写入特定格式的文件中. 本文将介绍 Hadoop 如何设计 OutputFormat 接口 , 以及一些 ...
 - [转] - hadoop中使用lzo的压缩
		
在hadoop中使用lzo的压缩算法可以减小数据的大小和数据的磁盘读写时间,不仅如此,lzo是基于block分块的,这样他就允许数据被分解成chunk,并行的被hadoop处理.这样的特点,就可以让l ...
 - Hadoop工程包架构解析
		
Hadoop源码解析 1 --- Hadoop工程包架构解析 1 Hadoop中各工程包依赖简述 Google的核心竞争技术是它的计算平台.Google的大牛们用了下面5篇文章,介绍了它们的计算 ...
 - hadoop中MapReduce中压缩的使用及4种压缩格式的特征的比较
		
在比较四中压缩方法之前,先来点干的,说一下在MapReduce的job中怎么使用压缩. MapReduce的压缩分为map端输出内容的压缩和reduce端输出的压缩,配置很简单,只要在作业的conf中 ...
 
随机推荐
- Mutex vs Semaphore
			
What are the differences between Mutex vs Semaphore? When to use mutex and when to use semaphore? Co ...
 - jquery cookie 用法
			
jquery cookie 用法 $.cookie("name","value","options") 当不设置options时,此coo ...
 - 分析windows宿主机Ping不通linux虚拟机的其中一种情况
			
ping不通的情况是由于设置网络选项的时候,可以看到界面名称的选择如下(当前选择的是无线网卡驱动):
 - cogs 自己出的题目 题解报告
			
第一题很简单嘛,就是裸的动态树分治嘛 对于每一层的重心维护子树路径的信息和子树到上一层重心的点的信息 空间复杂度O(nlogn) 对于每一层我们按dis排序,之后记录军队数量的前缀和 查询的时候我们只 ...
 - platform_driver_register(),platform_device_register()区别
			
设备与驱动的两种绑定方式:在设备注册时进行绑定及在驱动注册时进行绑定. 以一个USB设备为例,有两种情形: (1)先插上USB设备并挂到总线中,然后在安装USB驱动程序过程中从总线上遍历各个设备,看驱 ...
 - mysql级联删除更新
			
首先,目前在产品环境可用的MySQL版本(指4.0.x和4.1.x)中,只有InnoDB引擎才允许使用外键,所以,我们的数据表必须使用InnoDB引擎. 下面,我们先创建以下测试用数据库表: CREA ...
 - yum工具介绍
			
当你的linux处于联网状态时,yum工具能够非常方便的在Linux上安装各种软件.补丁等等,而且最重要的一点是完全不用管包的依赖关系.只需要简单的指定你要安装的软件名称,其他工作几乎都交给yum了, ...
 - AC题目简解-数论
			
反素数: HDU2521定义对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x ...
 - OpenCV源码阅读(3)---matx.h---学习心得
			
在.h文件里定义类,可以通过内联函数的方法完成类基础函数的实现,这样就不需要额外写.cpp文件来写类的内容. 对于操作符重载,可以使用返回应用的方式减小内存开销 _Tp& someclass: ...
 - JVM学习笔记(一)------基本结构
			
从Java平台的逻辑结构上来看,我们可以从下图来了解JVM: 从上图能清晰看到Java平台包含的各个逻辑模块,也能了解到JDK与JRE的区别 对于JVM自身的物理结构,我们可以从下图鸟瞰一下: 对于J ...