天天看點

Hadoop學習筆記(一):MapReduce的輸入格式

    hadoop學習有一段時間了,但是缺乏練手的項目,老是學了又忘。想想該整理一個學習筆記啥的,這年頭打字比寫字友善。果斷開部落格,咩哈哈~~

    開場白結束(木有文藝細胞)

    預設的mapreduce作業

       這些個預設設定都不需要顯式的設定,但是需要知道預設設定的是啥,貼出來省的忘記了。要注意的是:

       1) conf.setinputformat(textinputformat.class);  預設的輸入格式;

       2) conf.setmapoutputkeyclass(longwritable.class); conf.setmapoutputvalueclass(text.class); 預設的map輸出格式,其實就是将原樣輸出而已;

       3) conf.setpartitionerclass(hashpartitioner.class); 預設的分區函數,沒有特殊操作都會使用這個了。具體算法是:return (key.hashcode()&integer.max_value)%numpartitions;

       4) conf.setoutputkeyclass(longwritable.class); conf.setoutputvalueclass(text.class);還是原樣輸出的格式。

      輸入分片

     一個輸入分片(split)是指由單個map處理的輸入塊,每個map操作之處理一個輸入分片。

     包含一個一位元組為機關的長度和一組存儲位置(即一組主機名)。

     inputsplit由inputformat建立。inputformat負責産生輸入分片并将它們分割成記錄。

     fileinputformat類

    所有使用檔案作為其資料源的inputformat實作的基類。

     提供兩個功能:  1)定義哪些檔案包含在一個作業的輸入中;

                           2)未輸入檔案生成分片的實作。

    輸入分片大小: 由最小分片大小、最大分片大小、塊大小決定。分片大小在[最小分片大小,最大分片大小]區間内,且取最接近塊大小的值。

    fileinputformat的子類:textinputformat(預設類型,鍵是longwritable類型,值為text類型,key為目前行在檔案中的偏移量,value為目前行本身);

                                     keyvaluetextinputformat(适合檔案自帶key,value的情況,隻要指定分隔符即可,比較實用);

                                     nlineinputformat(key為目前行在檔案中的偏移量,value為目前行本身,和textinputformat不同的是這個類型會為每個mapper指定固定行數的輸入分片,n為每個mapper收到的輸入行數;

                                     mapred.line.input.format.linespermap屬性控制n的值);

                                     sequencefileinputformat(使用sequencefile作為map的輸入)。

     dbinputformat類

     資料庫輸入,在map中使用jdbc操作資料庫,由于多個map将并發操作,故最好用于加載小量的資料集。操作資料庫一般使用sqoop。

    textoutputformat類

    把每條記錄寫為文本行,每個鍵值使用制表符分割,(當然也可以使用mapred.textoutputformat.separator屬性改變預設的分隔符)與textoutputformat對應的輸入格式是keyvaluetextinputformat。可以用nullwritable來省略輸出的鍵或者值(或者兩個都省略,即相當于

    nulloutputformat)

    sequencefileoutputformat類

    即以sequencefile的格式輸出,如果輸出需要作為後續mapreduce作業的輸入,這是一種很好的輸出格式。格式緊湊,容易被壓縮。

   (昨天弄到太晚了,代碼寫完直接睡了,今天上。。。)    

    multipleoutputformat類

    這個類可以将資料寫到多個檔案中,比較實用。比如将輸出的資料按一定的邏輯歸類到不同檔案中。(通常是按照輸出的鍵或者值中的資訊歸類)

    這個類有兩個實體子類:multipletextoutputformat,屬于textoutputformat的多版本檔案;

                                   multiplesequencefileoutputformat,屬于sequencefileoutputformat的多版本檔案。

    關鍵點:: multipleoutputformat類提供了一些子類覆寫來控制輸出檔案名的protected方法(generatefilenameforkeyvalue()方法),這個方法的傳回值将用來作為輸出的檔案名稱

    這裡提到一點,我使用的時候開始繼承的是multipletextoutputformat,但是怎麼調試都無效,還是輸出 part-00000檔案。然後各種查資料,最後好像網上有人說hadoop0.20.0版本還是之前的版本中存在bug,必須繼承multipleoutputformat類才有效。但是我裝的是hadoop1.04,不過我用的仍然是老版本的api在寫,不知道是否是這個原因,有大神看到的話幫忙解惑下,這裡謝謝了!

    下面是我繼承multipleoutputformat類實作reducer輸出到多個檔案的代碼:

    這裡面引用了兩個幫助類:jobbuilder,ncdcrecordparser。之後的筆記中也會使用到,就一并在這裡貼出來了。

jobbuilder:

ncdcrecordparser:

    輸出檔案截個圖吧:

Hadoop學習筆記(一):MapReduce的輸入格式

   截圖中看到的是以getstationid()命名的子檔案夾,在這些檔案夾中是以getyear()命名的檔案。

   multipleoutputs類

   這個類用于在原有輸出基礎上附加輸出,輸出是指定名稱的,可以寫到一個檔案或者多個檔案中。

   使用這個類的靜态方法addmultinamedoutput來設定輸出名稱,(其實是輸出檔案名的字首了,後面都會加上其他資料)

   需要注意的一點是,在這個靜态方法中指定的名稱,必須在reducer中的multipleoutputs類的執行個體方法 getcollector中接收,即作為這個方法的第一個參數傳入,不對應的話我試了下會報錯。這個報錯是因為啥呢?(沒找到,或者我還沒了解到,以後補充吧,同時希望看到文章的大神幫忙解惑,這裡謝謝了!)

   下面是實作的代碼,同樣使用到了上面貼出來的幫助類:

    下面是運作結果截圖:

Hadoop學習筆記(一):MapReduce的輸入格式

     截圖中看到的是以"station"+getstationid()+partnum命名的檔案。

     上面主要介紹了mapreduce作業使用到的一些常用的輸入格式,輸出格式。(都是書本上的理論知識了,隻能拿書本上的例子來練手,哎 苦于無項目實戰,自己買機器配叢集太不現實了,而且也搞不到實際需求和實際資料。悲催~~)