2011-01-19 14 views
1

MapReduceのMapおよびReduceでリレーション名を使用する方法はありますか?私はHadoopのMapReduceを使ってSetの違いをしようとしています。HadoopのMapReduceでリレーション名/テーブル名/ファイル名を使用する

入力: 2つのファイルRおよびSには用語のリストが含まれています。 (Amは用語を示すためにトンを使用する予定)

目的: 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が意図された方法です。
あなたの問題は実際にn倍のHDFSに同じ値を書いていたと思いますか?

EDIT: ダウンが私のコメントから貼り付け

ああ、私はそれを得た;)私は「古い」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

+0

ああ私はそれを得た;)私は本当に "古い" APIに精通していないが、リポーターを照会することができます:reporter.getInputSplit()。これはInputSplitというインターフェースを返します。これは "FileSplit"にキャスト可能です。 FileSplitオブジェクト内では、 "split.getPath()"を使ってパスを取得できます。また、PathオブジェクトからgetName()メソッドを呼び出すだけで済みます。 –

+1

Thanks much Thomas :)それは明示的なキャストで働いていました。 – Arnkrishn

関連する問題