2013-02-26 27 views
8

由於它突出了MultipleTextOutputFormat尚未遷移到新的API。因此,如果我們需要選擇一個輸出目錄並根據正在寫入的鍵值輸出fiename,那麼我們對新的mapreduce API有何選擇?新API中的MultipleTextOutputFormat替代

回答

4

我正在使用AWS EMR Hadoop 1.0.3,並且可以根據k/v對指定不同的目錄和文件。使用以下任一功能從MultipleOutputs類:

public void write(KEYOUT key, VALUEOUT value, String baseOutputPath) 

public <K,V> void write(String namedOutput, K key, V value, 
         String baseOutputPath) 

前者write方法要求的關鍵,是相同的類型作爲地圖輸出密鑰(如果你正使用該在映射器中)或與縮小輸出鍵相同的類型(如果您正在使用reducer)。該值也必須以類似的方式輸入。

後者write方法需要鍵/值類型時設定使用addNamedOutput函數MultipleObjects靜態屬性,以匹配所指定的類型:

public static void addNamedOutput(Job job, 
           String namedOutput, 
           Class<? extends OutputFormat> outputFormatClass, 
           Class<?> keyClass, 
           Class<?> valueClass) 

所以如果你需要不同的輸出類型比Context使用,您必須使用後者write方法。

的竅門能讓不同的輸出目錄是通過一個baseOutputPath包含目錄分隔符,就像這樣:

multipleOutputs.write("output1", key, value, "dir1/part"); 

在我而言,這創建了一個名爲「DIR1 /一部分-R-00000」的文件。

我沒有成功使用包含..目錄的baseOutputPath,因此所有baseOutputPath嚴格包含在傳遞給-output參數的路徑中。

有關如何設置和正確使用MultipleOutputs的更多細節,請參閱我找到的代碼(不是我的,但我發現它非常有用;不使用不同的輸出目錄)。 https://github.com/rystsov/learning-hadoop/blob/master/src/main/java/com/twitter/rystsov/mr/MultipulOutputExample.java

+0

我忘了提及我測試了基於鍵/值數據改變'baseOutputPath',併成功輸出到不同的文件。 – Eddified 2013-10-11 17:34:00

+0

我很高興你提到它,我已經發現它最終雖然:) – Amar 2013-10-15 18:52:45

+0

非常感謝「dir1/part」部分,不會想到這一點! – ssgao 2014-05-01 02:21:20

0

類似:Hadoop Reducer: How can I output to multiple directories using speculative execution?

基本上你可以直接從減速到HDFS寫 - 你只需要警惕投機性執行和唯一命名您的文件,那麼你就需要實現你自己的OutputCommitter清理中止的嘗試(如果您有真正的動態輸出文件夾,這是最困難的部分 - 您需要遍歷每個文件夾並刪除與中止/失敗任務關聯的嘗試)。一個簡單的解決方法是關閉推測執行

+0

這聽起來不簡單:P對於MultipleTextOutputFormat任何解決方法?或者我們可以使用新的API實現類似MultipleTextOutputFormat的東西嗎? – Amar 2013-02-27 09:56:23

+0

正如多個輸出的javadoc中所述,我在作業和縮減器中添加了下面的代碼,它工作正常。在作業中: MultipleOutputs.addNamedOutput(job,namedoutputstring,outputformatclass,keyclass,valueclass); 在減速器中: mos = new MultipleOutputs (context); ... /*在運行時計算*/baseoutput =「abc/xyz/filename」; mos.write(key,value,baseOutput); – techuser 2013-03-06 19:34:10

+0

不要忘記清理()中的mos.close()。 – 2013-10-11 20:44:27

-1

爲最佳答案,轉向Hadoop的 - (首發控衛253)的權威指南第三版

一個從HDG書摘 -

「在舊的MapReduce API中,有兩個類用於生成多個輸出:MultipleOutputFormat和MultipleOutputs。簡而言之,MultipleOutputs功能更全面,但MultipleOutputFormat更多地控制輸出目錄結構和文件命名。在舊API中結合了兩個多輸出類的最佳特性。「

它舉例說明如何使用MultipleOutputs API控制目錄結構,文件命名和輸出格式。

HTH。

+0

MultipleOutputs是否允許根據鍵值對快速決定輸出文件夾名稱或文件名?我不這麼認爲,如果有任何方法請讓我知道。 – Amar 2013-02-27 09:30:25

+0

是的,夥計,我找不到它!使用MultipleOutputs,你只能寫入一組*預定義的文件路徑。你可以在'run()'中使用'MultipleOutputs.addNamedOutput()'來做到這一點。我可能會在這裏丟失一些東西,但不是做出這樣的陳述,如果它很容易在其他地方找到,那麼你至少可以發佈一個鏈接。 – Amar 2013-02-27 16:24:30

+0

我也懷疑你已經使用了MultipleTextOutputFormat或MultipleOutputs!在閱讀本書時,它明確指出,就在示例之前:*與MutipleTextOutputFormat相比,使用MultipleOutputs *時對輸出命名的控制較少。 – Amar 2013-02-27 16:30:33