2011-01-19 54 views
1

有沒有辦法在MapReduce的Map和Reduce中使用關係名?我正在嘗試使用Hadoop的MapReduce來實現差異化。在Hadoop的MapReduce中使用關係名/表名/文件名

輸入: 2個文件R和S包含術語列表。 (我要去用t表示的術語)

目的:要查找的R - S,在R和不屬於S即術語

方法:

映射:吐出ŧ - > R或t - > S,這取決於t是來自R還是S.因此,映射輸出將t作爲關鍵字,將文件名稱作爲值。

減速器:如果t的值列表只包含R,則輸出t - > t。

我需要一些如何用文件名標記條款嗎?或者還有其他方法嗎?

我爲Set Union所做的事情的源代碼(在這種情況下不需要任何文件名)。只是想以此爲例來說明Mapper中文件名的不可用性。

public class Union { 
     public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, Text> { 

       public void map(LongWritable key, Text value, OutputCollector output, Reporter reporter) throws IOException { 
         output.collect(value, value); 
       } 
     } 

     public static class Reduce extends MapReduceBase implements Reducer<Text, Text, Text, Text> { 

       public void reduce(Text key, Iterator<Text> values, OutputCollector<Text, Text> output, Reporter reporter) throws IOException{ 
         while (values.hasNext()) 
         { 
           output.collect(key, values.next()); 
           break; 
         } 
       } 
     } 

     public static void main(String[] args) throws Exception { 
       JobConf conf = new JobConf(Union.class); 
       conf.setJobName("Union"); 
       conf.setOutputKeyClass(Text.class); 
       conf.setOutputValueClass(Text.class); 

       conf.setMapperClass(Map.class); 
       conf.setCombinerClass(Reduce.class); 
       conf.setReducerClass(Reduce.class); 
       conf.set("mapred.job.queue.name", "myQueue"); 
       conf.setNumReduceTasks(5); 

       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); 
     } 
} 

正如您所看到的,我無法確定哪個鍵 - >值對(輸入到映射器)來自哪個文件。我在這裏忽略簡單的東西嗎?

非常感謝。

回答

3

我會實現你的問題,就像你回答。這正是MapReduce的意圖。
我猜你的問題實際上是將相同的值寫入HDFS的n倍?

編輯: 從我的評論粘貼在那兒

啊我得到了它;)我不是很熟悉的「老」的API,但你可以「查詢」的記者用:

reporter.getInputSplit(); 

這將返回一個名爲InputSplit的接口。這很容易轉換爲「FileSplit」。在FileSplit對象中,您可以使用「split.getPath()」獲取路徑。從Path對象中,您只需調用getName()方法。

所以這個段應爲你工作:

FileSplit fsplit = reporter.getInputSplit(); // maybe cast it down to FileSplit if needed.. 
String yourFileName = fsplit.getPath().getName(); 
+0

感謝托馬斯。我更新了我的問題,我的代碼片段。我希望它能澄清我的問題。我更關心如何在映射器中獲取文件名。 – Arnkrishn 2011-01-20 00:37:58