0

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

私が行ったことの1つは、次のようにすべての(分割できない)タイルで実行されるマッパーを作成したことです。

public void map(Text keyT, ImageWritable value, Context context) throws IOException, InterruptedException {

     String key = keyT.toString();

    //check whether file needs to be processed
     if(key.startsWith(context.getJobName(), 0)){

         String newKey = key.substring(0, key.length()-1);
         ImageWritable iw = subSample(value);
         char region = key.charAt(key.length()-1);
         iw.setRegion(region);
         context.write(new Text(newKey), iw);
     }else{
         //tile not needed in calculation
     }
 }

私のレデューサーは次のようになります。

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

    ImageWritable higherLevelTile = new ImageWritable();
    int i = 0;
    for(ImageWritable s : values){
        int width = s.getWidth();
        int height = s.getHeight();
        char c = Character.toUpperCase(s.getRegion());
        int basex=0, basey=0;
        if(c=='A'){
            basex = basey = 0;
        }else if(c=='B'){
            basex = width;
            basey = 0;
        }else if(c=='C'){
            basex = 0;
            basey = height;             
        }else{
            basex = width;
            basey = height;
        }

        BufferedImage toDraw = s.getBufferedImage();
        Graphics g = higherLevelTile.getBufferedImage().getGraphics();
        g.drawImage(toDraw, basex, basey, null);
    }               
    context.write(key, higherLevelTile);

}

私のコードから導き出せるかもしれないので、hadoopは次のように実行されると期待していました:1)レベル1のすべてのタイルをマップします2)最初のリデュースを実行します。ここでは、Iterable値に4つの要素があると予想しました。下位レベルの4つのサブサンプリングされたタイルです。3)現在コンテキスト内にあるすべてのタイルをマップします。4)コンテキスト内のすべてのタイルを減らします。繰り返しますが、反復可能な値には4つの要素があります... 5)...繰り返し... 6)マップが残っていない場合->出力の書き込み

結局のところ、それは正しくありません。私のレデューサーはすべてのマップの後に呼び出され、Iterableには複数の要素が含まれているようには見えません。Iterableに2つの要素があると仮定してレデューサーコードを少し変更することでこれを修正しようとしました。1つはサブサンプリングされた値で、もう1つは部分的に完成した高レベルのタイルです。結局のところ、それも正しくありません。

誰かが私に、hadoopの流れが実際にどのようになっているのかを教えたり、指示したりできますか?ユースケースを機能させるにはどうすればよいですか?はっきり説明したいと思います。

4

1 に答える 1

3

最初のリデュースが始まる前にすべてのマップが完了するというあなたの仮定は正しいです。これは、各リデュースがソートされた順序で入力を取得することが保証されており、最後に終了するマップがすべてのリデュースの最初のキーを生成する可能性があるためです。

各マップはその出力を生成し、パーティショナーと呼ばれるプラグ可能なインターフェイスが各キーを受け取る必要のあるリデュースを選択します。デフォルトではkey.hashCode() % num_reduces、が使用されます。これは、通常の場合に適切な分散が得られるためです。要件がないので、それはあなたの問題かもしれません、、、"A"そして"AB"同じ"ABC"削減に行きます。

最後に、各reduceは、そのキーごとに1回呼び出されます。イテレータは、同じキーに関連付けられた値を調べます。値は通常ソートされていませんが、2次ソートで制御できることに注意してください。

http://riccomini.name/posts/hadoop/2009-11-13-sort-reducer-input-value-hadoop/をご覧ください。

二次ソートの例が必要な場合は、それを作成してHadoopの例に入れました。http://svn.apache.org/repos/asf/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-mapreduce-examples/src/main/java/org/apache/hadoop/examples/SecondarySort.java

于 2012-11-17T15:56:49.837 に答える