2

特定の解像度でマップ データを計算する Hadoop アプリケーションを作成しています。私の入力ファイルは、QuadTile原則に従って名前が付けられたマップのタイルです。それらをサブサンプリングし、より広い領域をカバーするが解像度が低い特定の上位レベルのタイルが得られるまで、それらをつなぎ合わせる必要があります。グーグルマップのズームアウトのように。

現在、マッパーはタイルをサブサンプリングし、リデューサーは特定のレベルのタイルを組み合わせて、1 レベル上のタイルを形成します。だから、とても良いです。しかし、必要なタイルに応じて、それらのマップを繰り返して、ステップ ax 回を減らす必要がありますが、これまではできませんでした。

そうするための最良の方法は何ですか?一時ディレクトリにタイルを明示的に保存せずに、必要なものが得られるまでそれらの一時ディレクトリで新しい mapreduce ジョブを開始することは可能ですか? 私が完璧な解決策だと思うのは、「while(context.hasMoreThanOneKey()){iterate mapreduce}」のようなものです。

答えに続いて、Job を拡張するクラス TileJob を作成しました。ただし、mapreduce はまだチェーンされていません。私が間違っていることを教えていただけますか?

public boolean waitForCompletion(boolean verbose) throws IOException, InterruptedException, ClassNotFoundException{

    if(desiredkeylength != currentinputkeylength-1){            
        System.out.println("In loop, setting input at " + tempout);
        String tempin = tempout;
        FileInputFormat.setInputPaths(this, tempin);            
        tempout = (output + currentinputkeylength + "/");
        FileOutputFormat.setOutputPath(this, new Path(tempout));
        System.out.println("Setting output at " + tempout);
        currentinputkeylength--;
        Configuration conf = new Configuration();
        TileJob job = new TileJob(conf);
        job.setJobName(getJobName());
        job.setUpJob(tempin, tempout, tiletogenerate, currentinputkeylength);       
         return job.waitForCompletion(verbose);

    }else{
        //desiredkeylength == currentkeylength-1
        System.out.println("In else, setting input at " + tempout);

        String tempin = tempout;
        FileInputFormat.setInputPaths(this, tempin);            
        tempout = output;
        FileOutputFormat.setOutputPath(this, new Path(tempout));
        System.out.println("Setting output at " + tempout);
        currentinputkeylength--;
        Configuration conf = new Configuration();
        TileJob job = new TileJob(conf);
        job.setJobName(getJobName());
        job.setUpJob(tempin, tempout, tiletogenerate, currentinputkeylength);
        currentinputkeylength--;

        return super.waitForCompletion(verbose);
    }   

}
4

1 に答える 1

1

通常、ジョブ、構成、および形式の種類 (入力と出力) を構成するドライバー クラスの main メソッドを使用して、mapreduce ステップを開始します。すべての準備が整うと、メイン メソッドは Job::waitForCompletion() を呼び出します。Job::waitForCompletion() はジョブを送信し、ジョブが完了するのを待ってから続行します。

そのロジックの一部を、条件が満たされるまで繰り返し Job::waitForCompletion() を呼び出すループにラップできます。カウンターを使用して基準を実装できます。reduce() メソッドにロジックを挿入して、キーの数でカウンターを設定またはインクリメントします。ドライバー クラスのループは、その (分散された) カウンターの値を Job インスタンスから取得でき、その値を使用して while 式をコーディングします。

どのファイルの場所を使用するかはあなた次第です。このドライバー ループ内で、入力と出力のファイルの場所を変更したり、それらを同じに保つことができます。

先に進んで、ループ内に新しいジョブと構成のインスタンスを作成する必要があることを付け加えておく必要があります。この状況でそれらのオブジェクトが再利用可能かどうかはわかりません。

public static void main(String[] args) {
    int keys = 2;
    boolean completed = true;
    while (completed & (keys > 1)) {

        Job job = new Job();

            // Do all your job configuration here

        completed = job.waitForCompletion();
        if (completed) {
            keys = job.getCounter().findCounter("Total","Keys").getValue();
        }
    }

}
于 2012-11-18T14:37:46.387 に答える