若不拷貝,工程中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程序。