您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關hadoop作業引用第三方jar文件的原理解析是怎樣的,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
在eclipse中寫mapreduce程序, 引用第三方jar文件, 可以利用eclipse hadoop插件直接run on hadoop提交, 很方便. 不過插件版本要和eclipse匹配, 不然總是local執行, 在50070是沒有job產生的.
如果希望將程序發布成jar文件, 在namenode上通過命令行方式執行, 缺少了eclipse幫忙自動配置jar文件, 會遇到java.lang.ClassNotFoundException, 這個問題可分成兩種情況討論.
一. hadoop命令式如何執行的?
其實$HADOOP_HOME/bin/hadoop是一個腳本文件. 以下wordcount命令為例
bin/hadoop jar wordcount.jar myorg.WordCount /usr/wordcount/input /usr/wordcount/output
腳本文件解析參數, 配置類路徑等, 最終執行的是如下命令:
exec java -classpath $CLASSPATH org.apache.hadoop.util.RunJar $@
其中$CLASSPATH : 包含${HADOOP_CONF_DIR}, $HADOOP_HOME下的*.jar以及$HADOOP_CLASSPATH;
$@ : 所有腳本參數, 此處為jar后面的參數;
RunJar : 這個類的功能比較簡單, 將jar文件解壓到“hadoop.tmp.dir”目錄下, 然后執行我們指定的類, 此處即為myorg.WordCount
p.s. hadoop腳本比較完整的分析可參見<Hadoop作業提交分析>.
有RunJar執行WordCount后, 就進入我們的程序了, 需要配置mapper, reducer以及輸出輸出路徑等等, 最終通過執行job.waitForCompletion(true)向JobTracker提交這個作業.
到目前可知, 已經完成了本地執行部分, 如果這段時期發生ClassNotFoundException, 則可以在自己的腳本文件中配置$HADOOP_CLASSPATH, 包含需要的第三方jar文件, 再執行hadoop命令, 此為情況一.
二. JobTracker和TaskTracker如何獲得第三方jar文件?
有時候提交job之后, 在map或者reduce函數中也會產生ClassNotFoundException. 這是因為map或reduce可能在其他機器上執行, 那些機器沒有需要的jar文件, mapreduce作業交由JobTracker和TaskTracker執行, 兩者如何獲得第三方jar文件呢? 即為情況二.
我們首先來分析下mapreduce提交過程。
step 1.和2. 通過Job類提交作業, 獲得一個作業號, 并根據conf決定作業時提交給LocalJobRunner還是JobTracker
step 3. copy job resource
client將作業所需資源上傳到hdfs上, 如job split, jar文件等. JobClient通過configureCommandLineOptions函數處理jar文件, 該方法中通過job獲得這些參數內容
files = job.get("tmpfiles"); // 對應參數項-files libjars = job.get("tmpjars"); // 對應-libjars archives = job.get("tmparchives"); // 對應-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來指定運行的類, 如此hadoop就可以根據該class定位到所在的jar文件, 就是我們打包的jar, 將其上傳到hdfs上. 到此jobClient完成了資源復制過程, 這些資源可供JobTracker和TaskTracker使用.
step4-10. JobClient提交job并執行作業(JobTracker以及TaskTracker工作就不展開了, 詳見<Map-Reduce過程解析>).
三. 總結
要想讓mapreduce程序引用第三方jar文件, 可以采用如下方式:
通過命令行參數傳遞jar文件, 如-libjars等;
直接在conf中設置, 如conf.set(“tmpjars”,*.jar), jar文件用逗號隔開;
利用分布式緩存, 如DistributedCache.addArchiveToClassPath(path, job), 此處的path必須是hdfs, 即自己講jar上傳到hdfs上, 然后將路徑加入到分布式緩存中;
第三方jar文件和自己的程序打包到一個jar文件中, 程序通過job.getJar()將獲得整個文件并將其傳至hdfs上. (很笨重)
在每臺機器的$HADOOP_HOME/lib目錄中加入jar文件. (不推薦)
p.s. 如果通過上面方法1.或2., 需要注意Configuration問題, 需要通過getConf()函數獲得, 而不要自己new一個對象.
看完上述內容,你們對hadoop作業引用第三方jar文件的原理解析是怎樣的有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。