古詩詞大全網 - 成語故事 - 關於分布式Hadoop在WINDOWS上操作問題

關於分布式Hadoop在WINDOWS上操作問題

若在windows的Eclipse工程中直接啟動mapreduc程序,需要先把hadoop集群的配置目錄下的xml都拷貝到src目錄下,讓程序自動讀取集群的地址後去進行分布式運行(您也可以自己寫java代碼去設置job的configuration屬性)。

若不拷貝,工程中bin目錄沒有完整的xml配置文件,則windows執行的mapreduce程序全部通過本機的jvm執行,作業名也是帶有“local"字眼的作業,如 job_local2062122004_0001。 這不是真正的分布式運行mapreduce程序。

估計得研究org.apache.hadoop.conf.Configuration的源碼,反正xml配置文件會影響執行mapreduce使用的文件系統是本機的windows文件系統還是遠程的hdfs系統; 還有影響執行mapreduce的mapper和reducer的是本機的jvm還是集群裏面機器的jvm

二、 本文的結論

第壹點就是: windows上執行mapreduce,必須打jar包到所有slave節點才能正確分布式運行mapreduce程序。(我有個需求是要windows上觸發壹個mapreduce分布式運行)

第二點就是: Linux上,只需拷貝jar文件到集群master上,執行命令hadoop jarPackage.jar MainClassName即可分布式運行mapreduce程序。

第三點就是: 推薦使用附壹,實現了自動打jar包並上傳,分布式執行的mapreduce程序。

附壹、 推薦使用此方法:實現了自動打jar包並上傳,分布式執行的mapreduce程序:

請先參考博文五篇:

Hadoop作業提交分析(壹)~~(五)

引用博文的附件中EJob.java到妳的工程中,然後main中添加如下方法和代碼。

public static File createPack() throws IOException {

File jarFile = EJob.createTempJar("bin");

ClassLoader classLoader = EJob.getClassLoader();

Thread.currentThread().setContextClassLoader(classLoader);

return jarFile;

}

在作業啟動代碼中使用打包:

Job job = Job.getInstance(conf, "testAnaAction");

添加:

String jarPath = createPack().getPath();

job.setJar(jarPath);

即可實現直接run as java application 在windows跑分布式的mapreduce程序,不用手工上傳jar文件。

附二、得出結論的測試過程

(未有空看書,只能通過愚笨的測試方法得出結論了)

壹. 直接通過windows上Eclipse右擊main程序的java文件,然後"run as application"或選擇hadoop插件"run on hadoop"來觸發執行MapReduce程序的測試。

1,如果不打jar包到進集群任意linux機器上,它報錯如下:

[work] 2012-06-25 15:42:47,360 - org.apache.hadoop.mapreduce.Job -10244 [main] INFO org.apache.hadoop.mapreduce.Job - map 0% reduce 0%

[work] 2012-06-25 15:42:52,223 - org.apache.hadoop.mapreduce.Job -15107 [main] INFO org.apache.hadoop.mapreduce.Job - Task Id : attempt_1403517983686_0056_m_000000_0, Status : FAILED

Error: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class bookCount.BookCount$BookCountMapper not found

at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1720)

at org.apache.hadoop.mapreduce.task.JobContextImpl.getMapperClass(JobContextImpl.java:186)

at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:721)

at org.apache.hadoop.mapred.MapTask.run(MapTask.java:339)

at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:162)

at java.security.AccessController.doPrivileged(Native Method)

at javax.security.auth.Subject.doAs(Subject.java:415)

at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)

at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:157)

Caused by: java.lang.ClassNotFoundException: Class bookCount.BookCount$BookCountMapper not found

at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:1626)

at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1718)

... 8 more

# Error:後重復三次

2012-06-25 15:44:53,234 - org.apache.hadoop.mapreduce.Job -37813 [main] INFO org.apache.hadoop.mapreduce.Job - map 100% reduce 100%

現象就是:報錯,無進度,無運行結果。

2,拷貝jar包到“只是”集群master的$HADOOP_HOME/share/hadoop/mapreduce/目錄上,直接通過windows的eclipse "run as application"和通過hadoop插件"run on hadoop"來觸發執行,它報錯同上。

現象就是:報錯,無進度,無運行結果。

3,拷貝jar包到集群某些slave的$HADOOP_HOME/share/hadoop/mapreduce/目錄上,直接通過windows的eclipse "run as application"和通過hadoop插件"run on hadoop"來觸發執行

和報錯:

Error: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class bookCount.BookCount$BookCountMapper not found

at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1720)

at org.apache.hadoop.mapreduce.task.JobContextImpl.getMapperClass(JobContextImpl.java:186)

和報錯:

Error: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class bookCount.BookCount$BookCountReducer not found

現象就是:有報錯,但仍然有進度,有運行結果。

4,拷貝jar包到集群所有slave的$HADOOP_HOME/share/hadoop/mapreduce/目錄上,直接通過windows的eclipse "run as application"和通過hadoop插件"run on hadoop"來觸發執行:

現象就是:無報錯,有進度,有運行結果。

第壹點結論就是: windows上執行mapreduce,必須打jar包到所有slave節點才能正確分布式運行mapreduce程序。

二 在Linux上的通過以下命令觸發MapReduce程序的測試。

hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/bookCount.jar bookCount.BookCount

1,只拷貝到master,在master上執行。

現象就是:無報錯,有進度,有運行結果。

2,拷貝隨便壹個slave節點,在slave上執行。

現象就是:無報錯,有進度,有運行結果。

但某些節點上運行會報錯如下,且運行結果。:

14/06/25 16:44:02 INFO mapreduce.JobSubmitter: Cleaning up the staging area /tmp/hadoop-yarn/staging/hduser/.staging/job_1403517983686_0071

Exception in thread "main" java.lang.NoSuchFieldError: DEFAULT_MAPREDUCE_APPLICATION_CLASSPATH

at org.apache.hadoop.mapreduce.v2.util.MRApps.setMRFrameworkClasspath(MRApps.java:157)

at org.apache.hadoop.mapreduce.v2.util.MRApps.setClasspath(MRApps.java:198)

at org.apache.hadoop.mapred.YARNRunner.createApplicationSubmissionContext(YARNRunner.java:443)

at org.apache.hadoop.mapred.YARNRunner.submitJob(YARNRunner.java:283)

at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:415)

at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1268)

at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1265)

at java.security.AccessController.doPrivileged(Native Method)

at javax.security.auth.Subject.doAs(Subject.java:415)

at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)

at org.apache.hadoop.mapreduce.Job.submit(Job.java:1265)

at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1286)

at com.etrans.anaSpeed.AnaActionMr.run(AnaActionMr.java:207)

at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)

at com.etrans.anaSpeed.AnaActionMr.main(AnaActionMr.java:44)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:606)

at org.apache.hadoop.util.RunJar.main(RunJar.java:212)

第二點結論就是: Linux上,只需拷貝jar文件到集群master上,執行命令hadoop jarPackage.jar MainClassName即可分布式運行mapreduce程序。