2012-03-23 4 views
2
は、私は、以前のディレクトリ内のいくつかのファイルを移入されたHadoopの課題に取り組んでいます

は言うパート1 パート2HadoopのMultipleOutPutFormatと結合問合せ

私が原因でこのタスクを修正

一部-Oいくつかの出力をキャプチャするためにMultipleOutputsを使用しました。以前のいくつかのジョブマップ側のために、このディレクトリを使用していた:パート0 パート1 パート2 出力-1 出力-2 出力-3

問題が

のようなので、今のディレクトリ構造が見えます外部結合には使用できませんでしたが、今ではジョブは結合のためにpart- *ファイルしか使用せず、残りのファイルを破棄する必要があります。

i "は、" * /パート3

次式 jobConf.set(通り、 /パート2、/パート1、すなわちディレクトリ 分離などの入力を与える試み"mapred.join.expr"、CompositeInputFormat.compose(外側、 KeyValueTextInputFormat.class、パス[]))

は今私のパスは、[]の方法でealier 3で使用される5つのentires、出発3つのインデックスが含まれています/part-1、/part-2、*/part-3のパスと残りの2つは以前のものと同じです。

私はこの正しい方法で行っているかどうかはわかりませんが、私はこの結合が以前はoutput- *ファイルなしで動作するように動作するように提案してください。

上記の方法で例外を除いて投げています。

にjava.io.IOException:子1(12/6)からの一貫性のないスプリットカーディナリティ org.apache.hadoop.mapred.join.Parser $ CNode.getSplits(Parser.java:369) org.apache.hadoopコンポジット・インスタンスの作成:781) org.apache.hadoop.mapred.JobClient.submitJob(JobClient.java:730)

JobConf値は次のとおりです。

jobConf.setMapperClass(MyMapper.class); 
    jobConf.setReducerClass(MyReducer.class); 

    String[] foldersToJoin = StringUtils.split(getInputString(), Constants.COMMA); 
    Path[] pathsToJoin = new Path[foldersToJoin.length]; 
    int i = 0; 
    for(String folder : foldersToJoin){ 
     pathsToJoin[i++] = new Path(folder); 
    } 

FileOutputFormat.setOutputPath(jobConf, new Path("/MyOutPUT")); 

    jobConf.setInputFormat(CompositeInputFormat.class); 
    jobConf.set("mapred.join.expr", CompositeInputFormat.compose(Constants.OUTER_JOIN_OP, 
      KeyValueTextInputFormat.class, pathsToJoin)); 

    jobConf.setOutputFormat(TextOutputFormat.class); 
    jobConf.setOutputKeyClass(Text.class); 
    jobConf.setOutputValueClass(Text.class); 

    MultipleOutputs.addNamedOutput(jobConf, CHANGE_SET_A, 
      TextOutputFormat.class, Text.class, Text.class); 
    MultipleOutputs.addNamedOutput(jobConf, CHANGE_SET_B, 
      TextOutputFormat.class, Text.class, Text.class); 
    MultipleOutputs.addNamedOutput(jobConf,CHANGE_SET_C, 
      TextOutputFormat.class, Text.class, Text.class); 
    MultipleOutputs.addNamedOutput(jobConf, CHANGE_SET_D, 
      TextOutputFormat.class, Text.class, Text.class); 

それにコード

mapred.join.expr = CompositeInputFormat.compose(Constants.OUTER_JOIN_OP, 
     KeyValueTextInputFormat.class, pathsToJoin) 

    where pathsToJoin = new Path[]{new Path["/home/hadoop/folder1/part-1"], 
    new Path["/home/hadoop/folder1/part-2"],new Path["/home/hadoop/folder1/part-3"], 
    new Path["/home/hadoop/folder2"],new Path["/home/hadoop/folder3"] } 

ので、基本的に、私は唯一のpart- *ファイルを結合しようとしていますが、中に存在している私には、以下の「」区切りの文字列として、フォルダ内のすべてのファイルを追加していますfolder1 with folder2 and folder3

この種のシナリオに対する任意のドキュメントまたはリンクは大きな助けになります。

+0

ドライバコード(JobConf.setXXXメソッドを呼び出す場所)を投稿できますか?私はあなたが入力したファイルを定義する際に、より良いグロブを作成する必要があると思っています。 –

+0

が問題のjobConfコードを追加しました。 – dpsdce

+0

'pathsToJoin'配列の値はどこで設定していますか? –

答えて

3

私はこれを今理解していると思います。

あなたは、フォルダへの出力、その内容を持っているジョブの数を実行した:

job1 -> folder1 
job2 -> folder2 
job3 -> folder3 

今、あなたは、単一の各フォルダやプロセスの各パート-RXからの出力をマージするCompositeInputFormatを使用したいですマッパー

map0 - merged contents of folder1/part-r-0, folder2/part-r-0, folder3/part-r-0 
map1 - merged contents of folder1/part-r-1, folder2/part-r-1, folder3/part-r-1 
.. and so on .. 

あなたが持っている追加の複雑さは、ジョブの1以上であるが、MultipleOutputsを使用して、そうではなく、folder1の中に一部-RXファイルされた、あなたは

を持っています

そして、あなたはCompositeInputFormatを使用するために来たときにfolder1のは、私はあなたには、いくつかのグロブを使用するようにmapred.join.expr値を修正する必要があると思うこの場合

をフォルダ2以上のファイルを持っており、3ので、それはerroringです:

// use glob for folder1, to only include the part-x files (ignoring the output-x files) 
CompositeInputFormat.compose(Constants.OUTER_JOIN_OP, KeyValueTextInputFormat.class, 
    new Path[] { 
     new Path('folder1/part-*'), 
     new Path('folder2/part-r-*'), 
     new Path('folder3/part-r-*'), 
    }); 
+0

Chrisさん、ありがとうございました。私はこれをどんなものと同じように苦労していた。 hadoopをうまく保持する方法に関する提案やリソースは、私はHadoopプログラミングの初心者です。 – dpsdce

+1

トム・ホワイトの「Hadoopの最終ガイド」をすでに読んでいるとすれば、それ以外に何をしたいですか?ほとんどのものと同じように、実験をして、あなたの過ちから学びましょう –