今天就跟大家聊聊有關(guān)hadoop作業(yè)引用第三方j(luò)ar文件的原理解析是怎樣的,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
創(chuàng)新互聯(lián)建站專注于企業(yè)營銷型網(wǎng)站建設(shè)、網(wǎng)站重做改版、馬村網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5開發(fā)、商城建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為馬村等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
在eclipse中寫mapreduce程序, 引用第三方j(luò)ar文件, 可以利用eclipse hadoop插件直接run on hadoop提交, 很方便. 不過插件版本要和eclipse匹配, 不然總是local執(zhí)行, 在50070是沒有job產(chǎn)生的.
如果希望將程序發(fā)布成jar文件, 在namenode上通過命令行方式執(zhí)行, 缺少了eclipse幫忙自動(dòng)配置jar文件, 會(huì)遇到j(luò)ava.lang.ClassNotFoundException, 這個(gè)問題可分成兩種情況討論.
一. hadoop命令式如何執(zhí)行的?
其實(shí)$HADOOP_HOME/bin/hadoop是一個(gè)腳本文件. 以下wordcount命令為例
bin/hadoop jar wordcount.jar myorg.WordCount /usr/wordcount/input /usr/wordcount/output
腳本文件解析參數(shù), 配置類路徑等, 最終執(zhí)行的是如下命令:
exec java -classpath $CLASSPATH org.apache.hadoop.util.RunJar $@
其中$CLASSPATH : 包含${HADOOP_CONF_DIR}, $HADOOP_HOME下的*.jar以及$HADOOP_CLASSPATH;
$@ : 所有腳本參數(shù), 此處為jar后面的參數(shù);
RunJar : 這個(gè)類的功能比較簡單, 將jar文件解壓到“hadoop.tmp.dir”目錄下, 然后執(zhí)行我們指定的類, 此處即為myorg.WordCount
p.s. hadoop腳本比較完整的分析可參見
有RunJar執(zhí)行WordCount后, 就進(jìn)入我們的程序了, 需要配置mapper, reducer以及輸出輸出路徑等等, 最終通過執(zhí)行job.waitForCompletion(true)向JobTracker提交這個(gè)作業(yè).
到目前可知, 已經(jīng)完成了本地執(zhí)行部分, 如果這段時(shí)期發(fā)生ClassNotFoundException, 則可以在自己的腳本文件中配置$HADOOP_CLASSPATH, 包含需要的第三方j(luò)ar文件, 再執(zhí)行hadoop命令, 此為情況一.
二. JobTracker和TaskTracker如何獲得第三方j(luò)ar文件?
有時(shí)候提交job之后, 在map或者reduce函數(shù)中也會(huì)產(chǎn)生ClassNotFoundException. 這是因?yàn)閙ap或reduce可能在其他機(jī)器上執(zhí)行, 那些機(jī)器沒有需要的jar文件, mapreduce作業(yè)交由JobTracker和TaskTracker執(zhí)行, 兩者如何獲得第三方j(luò)ar文件呢? 即為情況二.
我們首先來分析下mapreduce提交過程。
step 1.和2. 通過Job類提交作業(yè), 獲得一個(gè)作業(yè)號(hào), 并根據(jù)conf決定作業(yè)時(shí)提交給LocalJobRunner還是JobTracker
step 3. copy job resource
client將作業(yè)所需資源上傳到hdfs上, 如job split, jar文件等. JobClient通過configureCommandLineOptions函數(shù)處理jar文件, 該方法中通過job獲得這些參數(shù)內(nèi)容
files = job.get("tmpfiles"); // 對(duì)應(yīng)參數(shù)項(xiàng)-files libjars = job.get("tmpjars"); // 對(duì)應(yīng)-libjars archives = job.get("tmparchives"); // 對(duì)應(yīng)-archives
如果jar文件有配置, 則將其加入到分布式緩存DistributedCache中, -libjars為例:
if (libjars != null) { FileSystem.mkdirs(fs, libjarsDir, mapredSysPerms); String[] libjarsArr = libjars.split(","); for (String tmpjars: libjarsArr) { Path tmp = new Path(tmpjars); Path newPath = copyRemoteFiles(fs, libjarsDir, tmp, job, replication); DistributedCache.addArchiveToClassPath(newPath, job); } }
另外, 在mapreduce程序的配置中總是需要job.setJarByClass來指定運(yùn)行的類, 如此hadoop就可以根據(jù)該class定位到所在的jar文件, 就是我們打包的jar, 將其上傳到hdfs上. 到此jobClient完成了資源復(fù)制過程, 這些資源可供JobTracker和TaskTracker使用.
step4-10. JobClient提交job并執(zhí)行作業(yè)(JobTracker以及TaskTracker工作就不展開了, 詳見
三. 總結(jié)
要想讓mapreduce程序引用第三方j(luò)ar文件, 可以采用如下方式:
通過命令行參數(shù)傳遞jar文件, 如-libjars等;
直接在conf中設(shè)置, 如conf.set(“tmpjars”,*.jar), jar文件用逗號(hào)隔開;
利用分布式緩存, 如DistributedCache.addArchiveToClassPath(path, job), 此處的path必須是hdfs, 即自己講jar上傳到hdfs上, 然后將路徑加入到分布式緩存中;
第三方j(luò)ar文件和自己的程序打包到一個(gè)jar文件中, 程序通過job.getJar()將獲得整個(gè)文件并將其傳至hdfs上. (很笨重)
在每臺(tái)機(jī)器的$HADOOP_HOME/lib目錄中加入jar文件. (不推薦)
p.s. 如果通過上面方法1.或2., 需要注意Configuration問題, 需要通過getConf()函數(shù)獲得, 而不要自己new一個(gè)對(duì)象.
看完上述內(nèi)容,你們對(duì)hadoop作業(yè)引用第三方j(luò)ar文件的原理解析是怎樣的有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。