2016-07-13 4 views
1

私はHadoopを使用してmapreduceプロジェクトを作成しています。私は現在、3つの順次ジョブを持っています。Hadoopカウンタの使用 - 複数のジョブ

私はHadoopカウンタを使用したいが、問題は最初のジョブで実際のカウントを行いたいが、3番目のジョブのレデューサーでカウンタ値にアクセスしたいということだ。

どうすればこの問題を解決できますか? enumはどこで定義しますか?私はそれを渡す必要がありますそれを2番目の仕事を投げた?また、何も見つからないので、これを行うためのコード例を見るのに役立ちます。

注:私はHadoopの2.7.2

EDITを使用しています:私はすでにアプローチはhereを説明し、それが成功しなかった試みました。私のケースは、私が別の仕事からカウンターにアクセスしたいのとは異なります。 (マッパーからレデューサーまで)。

私が実行しようとしました何: 最初の仕事を:

public static void startFirstJob(String inputPath, String outputPath) throws IOException, ClassNotFoundException, InterruptedException { 
    Configuration conf = new Configuration(); 
    Job job = Job.getInstance(conf, "wordCount"); 
    job.setJarByClass(WordCount.class); 
    job.setMapperClass(WordCountMapper.class); 
    job.setCombinerClass(WordCountReducer.class); 
    job.setReducerClass(WordCountReducer.class); 
    job.setOutputKeyClass(Text.class); 
    job.setOutputValueClass(LongWritable.class); 
    job.setInputFormatClass(SequenceFileInputFormat.class); 
    job.setOutputFormatClass(SequenceFileOutputFormat.class); 
    FileInputFormat.addInputPath(job, new Path(inputPath)); 
    FileOutputFormat.setOutputPath(job, new Path(outputPath)); 
    job.waitForCompletion(true); 
} 

定義された異なるクラスのカウンター列挙型:カウンターを読み取ろうと

public class CountersClass { 
    public static enum N_COUNTERS { 
     SOMECOUNT 
    } 
} 

Cluster cluster = new Cluster(context.getConfiguration()); 
Job job = cluster.getJob(JobID.forName("wordCount")); 
Counters counters = job.getCounters(); 
CountersClass.N_COUNTERS mycounter = CountersClass.N_COUNTERS.valueOf("SOMECOUNT"); 
Counter c1 = counters.findCounter(mycounter); 
long N_Count = c1.getValue(); 
+0

[?MRジョブに減らすタスクから成功したマップタスクの数にアクセスする方法がある(の可能性のある重複http://stackoverflow.com/questions:ちょうどたとえば、セットアップ()をオーバーライドし /8009802 /は - そこにある - 方法 - アクセス - 成功したマップ - タスク - から - 削減タスクの - から - ) – tworec

+0

私はそこからカウンターを使用することは良い考えではないと思う仕事を減らす。 http://stackoverflow.com/questions/8009802/is-there-a-way-to-access-number-of-successful-map-tasks-from-a-reduce-task-in-an/ – tworec

+0

はい、私はこれをすでに見ており、私はこのアプローチを試みました。しかし、その場合、彼は(同じ仕事の)減速機の中のカウンターを手に入れたいと思う。私の場合と同じではありません。 –

答えて

3

クラシックソリューションは、あなたがそれにアクセスする必要があり、後続ジョブの設定にジョブのカウンタ値を置くことです:

だから、カウントジョブマッパー/減速で正しくそれをインクリメントすることを確認してください:

context.getCounter(CountersClass.N_COUNTERS.SOMECOUNT).increment(1); 

そして、ジョブの完了をカウントした後:

job.waitForCompletion(true); 

Counter someCount = job.getCounters().findCounter(CountersClass.N_COUNTERS.SOMECOUNT); 

//put counter value into conf object of the job where you need to access it 
//you can choose any name for the conf key really (i just used counter enum name here) 
job2.getConfiguration().setLong(CountersClass.N_COUNTERS.SOMECOUNT.name(), someCount.getValue()); 

次の作品は、別のジョブのマッパー/減速でそれにアクセスすることです。

private long someCount; 

@Override 
protected void setup(Context context) throws IOException, 
    InterruptedException { 
    super.setup(context); 
    this.someCount = context.getConfiguration().getLong(CountersClass.N_COUNTERS.SOMECOUNT.name(), 0)); 
} 
+0

ありがとう!この 'enum'の中に複数のカウンタがあるとどうなりますか? 'setLong'と' getLong'を 'setEnum'と' getEnum'に置き換えることはできますか?それともあなたはすべてのカウンターのために言ったことをする必要がありますか? –

+1

各列挙型アイテムは別の設定キーに対応する必要があります。 setLong getLongを使用してそれぞれのキーでアクセスします – yurgis

+0

これは古い質問です。しかし、ジョブが遅れて開始したと仮定すると、遅延ジョブは、クラスタで実行されたときに以前に開始されたジョブによって設定されたカウンタを上書きしませんか? – user238607

2

取得あなたの第一仕事の最後にカウンターをつけて、その価値をファイルに書き込んで、あなたのサブセットで読んでくださいクエンントジョブ。レデューサーから読み込む場合はHDFSに、アプリケーションコードで読み込んで初期化する場合はローカルファイルに書き込みます。

Counters counters = job.getCounters(); Counter c1 = counters.findCounter(COUNTER_NAME); System.out.println(c1.getDisplayName()+":"+c1.getValue());

ファイルを読み込みと書き込みの基本的なチュートリアルの一部です。

+0

これはオプションかもしれません。これに必要なコードの部分を追加してください。おかげで –

関連する問題