Hadoop2.6.0子專案hadoop-mapreduce-examples的簡單介紹
引文
學習Hadoop的同學們,一定知道如果執行Hadoop自帶的各種例子,以大名鼎鼎的wordcount為例,你會輸入以下命令:
hadoop org.apache.hadoop.examples.WordCount -D mapreduce.input.fileinputformat.split.maxsize=1 /wordcount/input /wordcount/output/result1
當然,有些人還會用以下替代方式:
hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar wordcount /wordcount/input /wordcount/output/result1
相比於原始的執行方式,使用jar命令方式,讓我們不用再敲入繁瑣的完整包路徑。比如我們知道hadoop-mapreduce-examples專案中還提供了其它的例子,比如計算圓周率的例子,我們只需要記住此應用的簡單名字pi,就可以執行它:
hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar pi 5 10
雖說我們只是使用這些現成的例子,沒有必要較真,但是這種簡潔的使用方式,無疑還是值得借鑑的。本文將分析下這種方式實現的原理,有興趣的同學可以一讀。
原始碼分析
這一節,我們通過對hadoop-mapreduce-examples專案中的關鍵原始碼進行分析,理解簡潔執行的原理。在hadoop-mapreduce-examples專案的pom.xml檔案中配置了org.apache.hadoop.examples.ExampleDriver作為jar命令的入口,配置如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>org.apache.hadoop.examples.ExampleDriver</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
這決定了使用jar命令執行hadoop-mapreduce-examples-2.6.0.jar包時,實際執行了ExampleDriver的main方法,ExampleDriver的實現如下:
public class ExampleDriver {
public static void main(String argv[]){
int exitCode = -1;
ProgramDriver pgd = new ProgramDriver();
try {
pgd.addClass("wordcount", WordCount.class,
"A map/reduce program that counts the words in the input files.");
// 省略其它例子的註冊程式碼
pgd.addClass("pi", QuasiMonteCarlo.class, QuasiMonteCarlo.DESCRIPTION);
// 省略其它例子的註冊程式碼
exitCode = pgd.run(argv);
}
catch(Throwable e){
e.printStackTrace();
}
System.exit(exitCode);
}
}
以上程式碼構造了ProgramDriver的例項,並且呼叫其addClass方法,三個引數分別是例子名稱(如wordcount、pi等)、例子的實現Class、例子的描述資訊。ProgramDriver的addClass方法的實現如下:
public void addClass(String name, Class<?> mainClass, String description)
throws Throwable {
programs.put(name , new ProgramDescription(mainClass, description));
}
首先,構造ProgramDescription物件,其建構函式如下:
public ProgramDescription(Class<?> mainClass,
String description)
throws SecurityException, NoSuchMethodException {
this.main = mainClass.getMethod("main", paramTypes);
this.description = description;
}
其中main的型別是java.lang.reflect.Method,用於儲存例子Class的main方法。
然後,將例子名稱(如wordcount、pi等)和ProgramDescription例項註冊到programs中,programs的型別定義如下:
/**
* A description of a program based on its class and a
* human-readable description.
*/
Map<String, ProgramDescription> programs;
ExampleDriver的main方法在最後會呼叫ProgramDriver的run方法,其實現如下:
public int run(String[] args)
throws Throwable
{
// Make sure they gave us a program name.
if (args.length == 0) {
System.out.println("An example program must be given as the" +
" first argument.");
printUsage(programs);
return -1;
}
// And that it is good.
ProgramDescription pgm = programs.get(args[0]);
if (pgm == null) {
System.out.println("Unknown program `" + args[0] + "` chosen.");
printUsage(programs);
return -1;
}
// Remove the leading argument and call main
String[] new_args = new String[args.length - 1];
for(int i=1; i < args.length; ++i) {
new_args[i-1] = args[i];
}
pgm.invoke(new_args);
return 0;
}
ProgramDriver的run方法執行的步驟如下:
- 引數長度校驗;
- 根據第一個引數,從programs中查詢對應的ProgramDescription例項;
- 將其餘的引數傳遞給ProgramDescription的invoke方法,進而執行對應的例子。
ProgramDescription的invoke方法的實現如下:
public void invoke(String[] args)
throws Throwable {
try {
main.invoke(null, new Object[]{args});
} catch (InvocationTargetException except) {
throw except.getCause();
}
}
由此我們知道具體例子的執行,是通過反射呼叫具體例子Class的main方法,最終實現的。
後記:個人總結整理的《深入理解Spark:核心思想與原始碼分析》一書現在已經正式出版上市,目前京東、噹噹、天貓等網站均有銷售,歡迎感興趣的同學購買。
京東(現有滿150減50活動)):http://item.jd.com/11846120.html
噹噹:http://product.dangdang.com/23838168.html
相關文章
- 簡單介紹 Vue 3.0 專案建立Vue
- Vue3專案的簡單搭建與專案結構的簡單介紹Vue
- 簡單介紹VBS 批次Ping的專案實現
- 檔案管理簡單介紹
- NodeJS專案基礎結構簡單介紹NodeJS
- vue-cli快速構建專案簡單介紹Vue
- 面試時如何不簡單de介紹自己的專案經驗?面試
- ionic V3.10 新建空白專案中檔案的簡單介紹
- Webpack 的簡單介紹Web
- Promise的簡單介紹Promise
- CFRunloopObserverRef 的簡單介紹OOPServer
- 關於PHP檔案操作的簡單介紹PHP
- SVG簡單介紹SVG
- HTML簡單介紹HTML
- ActiveMQ簡單介紹MQ
- HTML 簡單介紹HTML
- JavaScript 簡單介紹JavaScript
- CSS 簡單介紹CSS
- SCSS 簡單介紹CSS
- UICollectionView 簡單介紹UIView
- css簡單介紹CSS
- SpringMvc的簡單介紹SpringMVC
- javascript的this用法簡單介紹JavaScript
- noscript的作用簡單介紹
- Redux的簡單概念介紹Redux
- ORACLE SEQUENCE的簡單介紹Oracle
- 【從零開始寫一個簡單的ImageLoader框架】專案介紹框架
- css引入外部css檔案的方式簡單介紹CSS
- RPC簡單介紹RPC
- spark簡單介紹(一)Spark
- Flutter key簡單介紹Flutter
- Python簡單介紹Python
- <svg>元素簡單介紹SVG
- Git_簡單介紹Git
- JSON簡單介紹JSON
- 簡單介紹克隆 JavaScriptJavaScript
- 簡單介紹 ldd 命令
- javascript物件簡單介紹JavaScript物件