若在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
現象就是:有報錯,但仍然有進度,有運行結果。