簡體   English   中英

如何在運行Hadoop MapReduce作業時將文件名/文件內容作為MAP的鍵/值輸入?

[英]How to get Filename/File Contents as key/value input for MAP when running a Hadoop MapReduce Job?

我正在創建一個分析PDF,DOC和DOCX文件的程序。 這些文件存儲在HDFS中。

當我啟動MapReduce作業時,我希望map函數將Filename作為鍵,將Binary Contents作為值。 然后我想創建一個流閱讀器,我可以將其傳遞給PDF解析器庫。 如何實現Map Phase的鍵/值對是filename / filecontents?

我正在使用Hadoop 0.20.2

這是開始工作的舊代碼:

public static void main(String[] args) throws Exception {
 JobConf conf = new JobConf(PdfReader.class);
 conf.setJobName("pdfreader");

 conf.setOutputKeyClass(Text.class);
 conf.setOutputValueClass(IntWritable.class);

 conf.setMapperClass(Map.class);
 conf.setReducerClass(Reduce.class);

 conf.setInputFormat(TextInputFormat.class);
 conf.setOutputFormat(TextOutputFormat.class);

 FileInputFormat.setInputPaths(conf, new Path(args[0]));
 FileOutputFormat.setOutputPath(conf, new Path(args[1]));

 JobClient.runJob(conf);
}

我知道還有其他inputformat類型。 但有沒有一個完全符合我的要求? 我覺得文檔很模糊。 如果有一個可用,那么Map函數輸入類型應該如何?

提前致謝!

解決方案是創建自己的FileInputFormat類來執行此操作。 您可以從此FileInputFormat接收的FileSplit訪問輸入文件的名稱(getPath)。 請務必否決FileInputformat的isSplitable以始終返回false。

您還需要一個自定義RecordReader,它將整個文件作為單個“Record”值返回。

處理太大的文件時要小心。 您將有效地將整個文件加載到RAM中,並且任務跟蹤器的默認設置是只有200MB RAM可用。

您可以使用WholeFileInputFormat( https://code.google.com/p/hadoop-course/source/browse/HadoopSamples/src/main/java/mr/wholeFile/?r=3

您可以通過此命令獲取文件的映射器名稱:

public void map(NullWritable key, BytesWritable value, Context context) throws 
IOException, InterruptedException 
{       

Path filePath= ((FileSplit)context.getInputSplit()).getPath();
String fileNameString = filePath.getName();

byte[] fileContent = value.getBytes();

}

作為您的方法的替代方案,可以直接將二進制文件添加到hdfs。 然后,創建一個包含所有二進制文件的dfs路徑的輸入文件。 這可以使用Hadoop的FileSystem類動態完成。 最后,創建一個映射器,通過再次使用FileSystem打開輸入流來處理輸入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM