2017-05-23 2 views
1

私はマッパとレデューサを設定せず、他のパラメータを自分のプログラムからジョブ設定に設定していないhadoop map-reduceプログラムで作業しています。私は、Jobが出力と同じ出力を出力ファイルに送ることを想定していました。 しかし、私はそれがタブ(私は推測)で区切られたすべての行と出力ファイルにいくつかのダミーの整数値を印刷していることがわかった。ここでMap-reduce出力ファイルで未知の整数値を取得する

は私のコードです:

import org.apache.hadoop.conf.Configured; 
import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.mapreduce.Job; 
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; 
import org.apache.hadoop.util.Tool; 
import org.apache.hadoop.util.ToolRunner; 

public class MinimalMapReduce extends Configured implements Tool { 

    public int run(String[] args) throws Exception { 

     Job job = new Job(getConf()); 
     job.setJarByClass(getClass()); 
     FileInputFormat.addInputPath(job, new Path(args[0])); 
     FileOutputFormat.setOutputPath(job, new Path(args[1])); 

     return job.waitForCompletion(true) ? 0 : 1; 
    } 

    public static void main(String[] args) { 
     String argg[] = {"/Users/***/Documents/hadoop/input/input.txt", 
          "/Users/***/Documents/hadoop/output_MinimalMapReduce"}; 
     try{ 
      int exitCode = ToolRunner.run(new MinimalMapReduce(), argg); 
      System.exit(exitCode); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

そして、ここでは、入力された:

0 2011 22 
8 2011 25 
16 2012 40 
24 2013 35 
32 2013 38 
40 2014 44 
48 2015 43 

どのように私は同じ出力に含まを得ることができます。

2011 22 
2011 25 
2012 40 
2013 35 
2013 38 
2014 44 
2015 43 

そして、ここでは、出力されます入力?

+2

これは、マッパーを指定しなくても、常に「IdentityMapper」が実行されるためです。各行の前にある_unknown integer_は、ファイルの先頭からのそれぞれの行のオフセットです。 – philantrovert

+0

@philantrovert私はこれを正しい答えとして掲示します。 –

+0

@BinaryNerdそれでは、あなたはそれをupvoteことを確認してください。私はあなたの目を保つだろう;) – philantrovert

答えて

0

私は@ philantrovertの答えに同意しますが、ここに私が見つけた詳細があります。 Hadoop- The Definitive Guideによれば、行番号にオフセットを加えるのはTextInputFormatです。TextInputFormatに関するドキュメントは次のとおりです。

TextInputFormatはデフォルトのInputFormatです。各レコードは入力行です。 LongWritableというキーは、ファイル内の行の先頭のバイトオフセットです。値は、行終端文字(改行や改行など)を除いた行の内容であり、Textオブジェクトとしてパッケージ化されています。だから、次のテキストを含むファイル:

On the top of the Crumpetty Tree 
The Quangle Wangle sat, 
But his face you could not see, 
On account of his Beaver Hat. 

は、4つのレコードの1つのスプリットに分割されています。レコードは、次のキーと値のペアとして解釈されます。

(0, On the top of the Crumpetty Tree) 
(33, The Quangle Wangle sat,) 
(57, But his face you could not see,) 
(89, On account of his Beaver Hat.) 

明らかに、キーは行番号がありません。これは、ファイルが行、境界ではなくバイトで分割されるという点で、一般的に実装することは不可能です。分割は独立して処理されます。行番号は実際には連続した概念です。あなたはそれらを消費するときに行数を保持しなければならないので、分割内の行番号を知ることは可能ですが、ファイル内では行えません。

ただし、それぞれの分割が前の分割のサイズを知っており、これを分割内のオフセットに追加してグローバルファイルを生成するため、各分割のファイル内のオフセットは他の分割とは独立して認識されますオフセット。オフセットは通常、各行に固有の識別子を必要とするアプリケーションには十分です。ファイルの名前と組み合わされて、ファイルシステム内で一意です。もちろん、すべての線が固定幅であれば、線の数を計算することは単にオフセットを幅で除算することに過ぎません。

2

私はそう

は、あなたがそれを仮定で正しかった

仕事を出力ファイルに入力と同じ出力を送信すると仮定しました。技術的には、ファイルにあるものを出力として取得しています。マッパーとレデューサーはKey-Valueペアを入力として使用します。

マッパーへの入力は、ファイルの入力分割であり、減速器への入力はマッパーの出力です。

しかし、私はそれがこれらのダミー整数は何もありませんが、最初からその行のオフセットタブ

で区切られたすべての行で出力ファイルにいくつかのダミーの整数値を印刷していることがわかりましたファイルのあなたが持っている各行は[4 DIGITS]<space>[2 DIGITS]<new-line>で構成されているため、オフセットは8個の倍数です。

マッパーまたはレデューサーを定義していないため、このオフセットが表示されるのはなぜですか?これは、マッパーが常に実行され、各行をオフセットにマッピングするこの作業を行い、IdentityMapperと呼ばれるためです。

入力と同じ出力を得るにはどうすればよいですか?

マッパーを定義して、入力ラインを出力にマップし、オフセットを取り除くことができます。上記のコードで

public void map(Object key, Text value, Context context 
        ) throws IOException, InterruptedException { 
    // Some cool logic here 
} 

keyダミー整数値、すなわちオフセットを含みます。 valueには、各行の値が1つずつ含まれます。 context.write関数を使用してvalueと記述し、次に減算器を使用せず、希望の出力を得るためにjob.setNumReduceTasks(0)を設定する独自のコードを書くことができます。

関連する問題