hadoop中的TextInputFormat類原始碼分析

逸卿發表於2014-05-06

在“天龍八部”(map+reduce執行的八大步驟)第一步的時候,需要指定用哪個類對輸入檔案進行格式化,程式碼是:job.setInputFromatClass(TextInputFormat.class)>(進入到原始碼),進入到TextInputFormat類中發現它繼承了FileInputFormat抽象類,而FileInputFormat繼承了InputFormat抽象類,在InputFormat抽象類中有兩個方法:一個是getSplits(),返回值是儲存inputSplit型別的集合List,它的作用是邏輯上拆分job提交的作業;另一個方法CreateRecordReader它建立了一個記錄讀取器(RecordReader,它是一個抽象類,裡面定義了抽象方法如:getcurrentKey(),getcurrentValue(),nextkeyvalue()等方法,它的實現類LineRecordReader實現了用於讀取給定的split(inputSplit型別)解析成鍵值對。

這兩個方法的具體實現在它的繼承類FileInputFormat類中,在這個方法中首先要獲取輸入資料夾中所有的檔案(List<FileStatus>files=listStatus(job)),然後迭代裡面的檔案,獲取檔案的資訊,之後判斷檔案是否為空和可以拆分,如果檔案非空但是不可以被拆分的話,會用一個類fileSplited封裝該檔案作為一個切片扔進list,(補充:split最小值的設定,在mapred.min.split.size中設定,預設是0,最大則是mapred.max.split.size沒有設定)

splitedsize的大小決定的原始碼(已簡化)是:

long minsize=Math.max(1L,mapred.min.splited.size)

long maxsize=Math.max(mapred.max.splited.size,263次方-1)

splitedsize=Math.max(minSize, Math.min(maxSize, blockSize))

總結,splitedsize的大小由minsizeblocksize決定,只有當minsize大於 64M才能改變(如果splitedsize大於blcoksize,有可能map需要的資料不再同一個datanode中,那麼就要從兩個datanode讀取資料,從而導致網路延遲,效率降低);當檔案可以拆分且不為空後,對輸入的文價進行按片大小進行拆分扔到list集合中;

LineRecordRead類完成了對切片鍵值對的生成,在方法nextkeyValue中有個一個LineReader工具類,呼叫其方法readLine()對切片進行讀取記錄長度,pos(偏移量)逐漸增大。

對輸人檔案生成鍵值對後,那麼他是如何與map扯上關係的呢?

map類中,有一個run()方法,裡面就有我們重寫的map()方法,在map方法裡面就呼叫了LineRecordReader類裡面的nextkeyvalue方法

原始碼分析主線:

 


 

相關文章