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