![](/img/trans.png)
[英]Getting Filename/FileData as key/value input for Map when running a Hadoop MapReduce Job
[英]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.