2017-09-26 3 views
1

私が使用している入力ファイルのパーティションの行インデックスを知る必要があります。私は行インデックスをデータに連結することでこれを元のファイルに強制することができますが、私はむしろHadoopでこれを行う方法を持っています。私はこれを私のマッパに持っています...Hadoopで入力ファイルのパーティションIDを取得する

String id = context.getConfiguration().get("mapreduce.task.partition"); 

"id"はどの場合でも0です。 「Hadoop:The Definitive Guide」では、パーティションIDのようなアクセスプロパティに「MapperまたはReducerのすべてのメソッドに渡されるコンテキストオブジェクトからアクセスできます」という記述があります。私が知る限り、この情報にアクセスする方法は実際にはありません。

私はContextオブジェクトのドキュメンテーションを調べましたが、これはそのようにしてスクリプトがコンパイルされるようです。しかし、私はすべての価値について0を得ているので、私は実際に正しいことを使っているかどうか分からず、これを理解するのに役立つオンラインの詳細を見つけることができません。

コードをテストするために使用される...

public class Test { 

public static class TestMapper extends Mapper<LongWritable, Text, Text, Text> { 

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { 
     String id = context.getConfiguration().get("mapreduce.task.partition"); 
     context.write(new Text("Test"), new Text(id + "_" + value.toString())); 
    } 
} 


public static class TestReducer extends Reducer<Text, Text, Text, Text> { 

    public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { 

     for(Text value : values) { 
      context.write(key, value); 
     } 
    } 
} 


public static void main(String[] args) throws Exception { 

    if(args.length != 2) { 
     System.err.println("Usage: Test <input path> <output path>"); 
     System.exit(-1); 
    } 

    Job job = new Job(); 
    job.setJarByClass(Test.class); 
    job.setJobName("Test"); 

    FileInputFormat.addInputPath(job, new Path(args[0])); 
    FileOutputFormat.setOutputPath(job, new Path(args[1])); 

    job.setMapperClass(TestMapper.class); 
    job.setReducerClass(TestReducer.class); 

    job.setOutputKeyClass(Text.class); 
    job.setOutputValueClass(Text.class); 

    System.exit(job.waitForCompletion(true) ? 0 : 1); 
} 
} 
+0

私は明確ではありません「入力ファイルのパーティションの行インデックス」が実際に何を意味するのかを示します。明確にできますか? –

+0

@BinaryNerd間違っているかもしれませんが、入力ファイルの行IDと思っていました。ファイル内に100行がある場合は、現在の行がマッパーが作業していることを知りたいと考えています(0-99または1-100の番号) – cpd1

答えて

1

二つのオプションは以下のとおりです。

  1. 使用ではなく、行番号
  2. トラックマッパーの行番号のオフセット

最初のものは、LongWritableというキーはproceされている行のオフセットを示しますssed。ラインの長さがまったく同じでない限り、オフセットからライン数を計算することはできませんが、それが有用な場合は、オーダーを決定することができます。

2番目のオプションは、マッパーでトラックを追跡することです。あなたが好きな何かにあなたのコードを変更することができます:

public static class TestMapper extends Mapper<LongWritable, Text, Text, Text> { 

    private long currentLineNum = 0; 
    private Text test = new Text("Test"); 

    public void map(LongWritable key, Text value, Context context) 
          throws IOException, InterruptedException { 

     context.write(test, new Text(currentLineNum + "_" + value)); 
     currentLineNum++; 
    } 
} 
+0

Hmm。私はおそらくオフセットを使用することができます。私はそれが6の倍数であることを知っていますし、ラインは同じ長さでなければなりません。あなたが上で提供したことについて、どのように現在の行がわかるでしょうか?私の前提はマッパーが同時に動作しているため、上記のカウンターがラインの正しい番号を持たない可能性があります。たとえば、終了する最初のマッパーが5行目のマッパーであれば、現在の行番号は1ではありませんか? – cpd1

+0

マッパーの各インスタンスは、ファイル内の行を順番に処理し/その作業を分割します。複数のマッパーを実行している場合は、それぞれが独自の分割を処理します。ファイルへの同時アクセスはありませんので、上で概説した簡単な方法を使用して行を追跡できます。入力が分割されていないことを確認する必要があるので、gz圧縮のようなものを使用してください。 –

+0

入手しました。どうもありがとうございました。私はそれが同時であると思ったので、変数はオフになりますが、大規模なデータセットでテストして、あなたが言及した通りに正確に動作します。すべての助けに感謝します。 – cpd1

0

また、タプルのラインとして、あなたの行列を表すことができ、あなたがファイルに読んでいるとき、あなたはその情報を持っているので、すべてのタプル上の行とCOLが含まれます。 2D配列を構成する空白またはカンマ区切りの値だけのファイルを使用している場合、マッパーで現在作業している行(行)を特定することは非常に難しいでしょう

関連する問題