Hadoop InputFormat介紹

Hadoop InputFormat介紹

1 概述

我們在編寫MapReduce程序的時候,在設置輸入格式的時候,會調用如下代碼:

job.setInputFormatClass(KeyVakueTextInputFormat.class)

通過上面的代碼來保證輸入的文件是按照我們想要的格式被讀取,所有的輸入格式都繼承於InputFormat,這是一個抽象類,其子類有專門用於讀取普通文件的FileInputFormatt,用於讀取數據庫文件的DBInputFromat,用於讀取HBase的TableInputFormat等等。如下圖是InputFormat的圖譜。

InputFormat類圖

2 InputFormat方法

從類圖中可以看出,InputFormat抽象類僅有兩個抽象方法:

public abstract List<InputSplit> getSplits(JobContext context)
public abstract RecordReader<K,V> createRecordReader(InputSplit split,TaskAttemptContext context)

getSplits()方法是邏輯上拆分作業的輸入文件集,然後將每個InputSplit分配給一個單獨的Mapper進行處理

注意:拆分是按輸入文件的邏輯分割,而輸入文件不會被物理分割成塊。每個切片都是一個<input-file-path,start,offset>的元組,InputFormat並創建相應的RecordReader讀取這些切片。

createRecordReader()方法是爲給定的切片創建一個記錄閱讀器。在切片被使用之前先調用RecordReader.initialize(InputSplit, TaskAttemptContext)方法。

通過InputFormat,MapReduce框架可以做到:
1. 驗證作業輸入的正確性
2. 將輸入的文件切割成邏輯分片(InputSplit),一個InputSplit將會分配給一個獨立的MapTask
3. 提供RecordReader實現,讀取InputSplit中的Kv對供Mapper使用。

不同的InputFormat會各自實現不同的文件讀取方法以及分片方式,每個輸入分片會被單獨的MapTask作爲數據源。下面將介紹InputSplit和RecordReader。

3 InputSplit介紹

MapTask的輸入是一個輸入切片,稱爲InputSplit。InputSplit也是一個抽象類,它在邏輯上包含給處理這個InputSplit的Mapper的所有KV對。不同類型的輸入格式對應不同類型的切片,下圖是InputSplit的類圖。

InputSplit

3.1 InputSplit方法

// 獲取切片大小,並且根據size對切片排序
public abstract long getLength()
// 獲取存儲該分片的數據所在的節點位置,其中的數據是本地的,位置信息不需要序列號
public abstract String[] getLocations()
// 獲取有關切片在那個節點上的信息,以及它是如何存儲在每個位置的
public SplitLocationInfo[] getLocationInfo()

4 RecordReader

RecorderReader將讀入到Map的數據拆分成KV對。RecorderReader也是一個抽象類。下面是RecordReader的類圖:

InputFormat類圖

接下來看一下RecordReader的源代碼:

public abstract class RecordReader<KEYIN, VALUEIN> implements Closeable {

  /**
   * 由一個InputSplit初始化
   */
  public abstract void initialize(InputSplit split,
                                  TaskAttemptContext context
                                  ) throws IOException, InterruptedException;

  /**
   * 讀取分片下一個KV
   */
  public abstract
  boolean nextKeyValue() throws IOException, InterruptedException;

  /**
   * Get the current key
   */
  public abstract
  KEYIN getCurrentKey() throws IOException, InterruptedException;

  /**
   * Get the current value.
   */
  public abstract
  VALUEIN getCurrentValue() throws IOException, InterruptedException;

  /**
   * 跟蹤讀取分片的進度
   */
  public abstract float getProgress() throws IOException, InterruptedException;

  /**
   * Close the record reader.
   */
  public abstract void close() throws IOException;
}

參考博文

http://www.cnblogs.com/shitouer/archive/2013/02/28/hadoop-source-code-analyse-mapreduce-inputformat.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章