我正在編寫Hadoop應用程序,但似乎我誤解了hadoop的工作原理。我的輸入文件是根據QuadTile原則命名的地圖。我需要對這些樣本進行二次抽樣,然後將這些樣本拼接在一起,直到我擁有一個覆蓋面積較大但分辨率較低的較高層次的拼貼。就像縮小在谷歌地圖。Hadoop數據和控制流程
一個我做的事情是,我已經寫了,其執行上的每個(unsplittable)瓷磚這樣的映射:
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)映射一級的所有圖塊 2)先執行一次減少。在這裏我預計Iterable值有四個元素:較低級別的四個子採樣瓦片。 3)當前在上下文中的地圖瓦片 4)縮小上下文中的所有瓦片。再次,Iterable值將有4個元素... 5)...重複... 6)當沒有更多的地圖離開 - >寫輸出
原來,這是不正確的。我的reducer在每個Map之後被調用,並且Iterable似乎不會有多個元素。我試圖通過假設Iterable會有2個元素來改變Reducer代碼來解決這個問題:一個子採樣值和一個部分完成的高級tile。原來,這也是不正確的。
有誰能告訴我,或者指向我,hadoop的流程究竟是怎樣的?我應該怎樣做我的用例工作?我希望我解釋清楚。
你說所有地圖在第一次減少開始之前完成。但在我當前的代碼中,這是在單節點模式下運行的,他們真的不會......在輸入文件被完全映射後執行reduce是否可能?由於我的tile不可解析,所以每次map任務後都會發生第一次reduce。感謝您的回答。 – KarelV
啊,我看到在我的驅動程序代碼中combinerclass被設置爲我的reducer,可能是一些複製的代碼,我完全忘了。我註釋到了代碼,現在只在所有映射完成後才發生縮減。現在我需要迭代地圖並減少操作,直到只剩下某個鍵,這應該是要求的拼貼。我將爲此啓動一個新問題。感謝您的回答。 – KarelV