2013-03-01 90 views
1

我寫了一個簡單的MapReduce代碼,它將調用外部jar中的幾個方法。我將這個jar添加到hadoop/lib文件夾中,並且正在拾取它。單節點集羣一切正常。我有一個多節點集羣,我想運行相同的代碼。我想知道是否有一種方法可以將我的jar複製到dfs,這樣我就不需要在所有節點上手動添加jar。我想將所有的jar添加到另一個文件夾(不是hadoop/lib)。是否有可能實現這一目標?即將外部參照添加到具有許多罐子的文件夾。我跟着cloudera博客做了同樣的事情,但仍然沒有幫助。任何指針都會很有幫助。我正在使用hadoop 1.0.4版本。Hadoop:外部jar文件夾參考

P.S:我在主作業罐中添加了所有外部罐。即使那樣它也沒有被拾起。

回答

2

有兩種機制,包括其他罐子到你的工作的類路徑:

如果您還沒有已經存儲在其中HDFS,你可以使用GenericOptionsParser的-libjars說法。這將導致JobClient將您的作業上傳到HDFS的臨時目錄中,並將它們包含在分佈式緩存中供您工作。對於這個工作,你需要通過ToolRunner.run界面運行你的工作:

public class MyJob extends COnfigured implements Tool { 
    public int run(String args[]) { 
    Job job = new Job(getConf()); 
    // configure your job 
    // .. 

    return job.waitForCompletion() ? 0 : 1; 
    } 

    public static void main(String args[]) throws Exception { 
    ToolRunner.run(new MyJob(), args)); 
    } 
} 

然後,你運行你的工作如下(將罐子1-3作業類路徑):

#> hadoop jar myjob.jar MyJob -libjars jar1.jar,jar2.jar,jar3.jar [other args] 

如果你的罐子已經在HDFS,那麼你只需要添加的罐子分佈式緩存:

public int run(String args[]) { 
    Job job = new Job(getConf()); 
    // configure your job 
    // .. 

    // acquire job configuration 
    Configuration conf = job.getConf(); 

    // create a FileSystem 
    FileSystem fs = FileSystem.get(fs); 

    DistributedCache.addFileToClassPath(new Path("/myapp/jar1.jar"), conf, fs); 
    DistributedCache.addFileToClassPath(new Path("/myapp/jar2.jar"), conf, fs); 
    DistributedCache.addFileToClassPath(new Path("/myapp/jar3.jar"), conf, fs); 

    return job.waitForCompletion() ? 0 : 1; 
} 

第二種方法唯一的缺點是,你不能引用任何類論文的jar你的工作保密(除非您也有客戶端副本,並且您配置了HADOOP_CLASSPATH env變量)。

+0

謝謝克里斯。我會嘗試這一點,如果它可以更新。對於第一種方法,是否可以將所有jar添加到文件夾中。類似於/ tmp/jars/*。我在問,因爲我有超過15-20個依賴的罐子。另外,我在幾個博客中讀到,如果我們在主jar文件夾中有lib文件夾,那麼lib文件夾中的jar將自動添加到classpath中。但它不適合我。你知道這件事嗎? – CRS 2013-03-02 18:38:04

+0

我有同樣的問題。我正在使用hadoop-2.5.2。我使用這種機制,(加入-libjars參數),它沒有工作。我也嘗試添加相關jar到我的MapReduce jar中,在它的lib目錄中。那也沒用。 – feroze 2015-09-02 00:46:52