2012-11-18 53 views
2

我正在寫一個Hadoop應用程序在一定的分辨率計算地圖數據。我的輸入文件是根據QuadTile原則命名的地圖。我需要對這些樣本進行二次抽樣,然後將這些樣本拼接在一起,直到我擁有一個覆蓋面積較大但分辨率較低的較高層次的拼貼。就像縮小在谷歌地圖。迭代Map和Reduce操作

目前我的Mapper子樣本瓷磚和我的縮減器將瓷磚組合成一定的層次並形成一層的瓷磚。所以這麼好。但根據我需要的瓦片,我需要重複這些地圖並將步驟縮短x倍,這是迄今爲止我無法做到的。

這樣做的最佳方式是什麼?是否有可能沒有明確地保存瓷磚在臨時目錄中,並開始一個新的地圖減少這些臨時目錄,直到我得到我想要的?我認爲完美的解決方案大致類似於'while(context.hasMoreThanOneKey()){iterate mapreduce}'。

經過一個答案,我現在已經寫了延伸工作類TileJob。但是,mapreduc仍然沒有鏈接。你能告訴我我做錯了什麼嗎?

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); 
    } 

} 

回答

1

通常你通過具有配置作業,配置和格式類型(輸入和輸出)的驅動器類主要方法踢映射縮減步驟關閉。一旦準備好了,主方法調用Job :: waitForCompletion()來提交作業並等待作業完成,然後繼續。

您可以將一些邏輯封裝在重複調用Job :: waitForCompletion()的循環中,直到符合條件。您可以使用計數器實施您的標準。將邏輯放入你的reduce()方法中,用鍵數設置或增加一個計數器。您的驅動程序類中的循環可以從Job實例中獲取該(分佈式)計數器的值,並使用該值對while表達式進行編碼。

你用什麼文件位置是由你。在這個驅動程序循環中,您可以更改輸入和輸出的文件位置,或保持它們相同。

我應該補充一點,你應該繼續並在循環內創建一個新的Job和Configuration實例。我不知道這些對象在這種情況下是可重用的。

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(); 
     } 
    } 

} 
+0

我改變了我的問題與我目前的問題。你能澄清我做錯了什麼嗎? – KarelV

+0

查看更新的答案 –

+0

非常感謝,那是做的工作。 – KarelV