MapReduce新版客戶端API源碼分析
使用MapReduce新版客戶端API提交MapReduce Job需要使用 org.apache.hadoop.mapreduce.Job 類。JavaDoc給出以下使用范例。
// Create a new Job
Job job = new Job(new Configuration());
job.setJarByClass(MyJob.class);// Specify various job-specific parameters job.setJobName("myjob"); job.setInputPath(new Path("in")); job.setOutputPath(new Path("out")); job.setMapperClass(MyJob.MyMapper.class); job.setReducerClass(MyJob.MyReducer.class); // Submit the job, then poll for progress until the job is complete job.waitForCompletion(true); </pre> <p>從方法名可以看出,MapReduce Job是通過調用Job類的waitForCompletion方法提交到MapReduce框架運行的,而實際上這個方法又調用了Job類的submit方法。submit方法完成全部的提交工作。</p>
submit方法創建一個JobSubmitter實例并通過該實例完成提交工作。創建JobSubmitter實例需要準備兩個參數,一個是代表所用文件系統的FileSystem實例,另一個是封裝了與MapReduce框架通信的具體協議的ClientProtocol實例。使用這兩個實例,JobSubmitter在與集群通信時就不需要關心集群的具體細節,因而其代碼可以寫成具有一定的通用性。JobSubmitter具體的提交過程與編寫客戶端程序無關,這里不深入分析。不過,這里有必要分析FileSystem實例和ClientProtocol實例的創建過程。
FileSystem實例和ClientProtocol實例均取自Job的一個私有屬性Cluster cluster,Cluster類接受一個封裝了客戶端程序提供的配置信息的Configuration對象被實例化,在Cluster實例化的過程中,Cluster的FileSystem屬性和ClientProtocal屬性得以確定,其中FileSystem屬性由 ClientProtocal屬性確定。因此,這里的關鍵問題是:ClientProtocal屬性怎么確定?Cluster使用線程上下文類加載器尋找所有實現了ClientProtocolProvider這個抽象類的類,對于找到的類依次實例化并傳遞客戶端程序提供的配置信息作為參數調用其 create方法,直到從返回值獲得一個ClientProtocol實例的引用或者遍歷結束。若獲得引用,這個被賦值給ClientProtocal屬性;否則輸出出錯信息并返回。
可見,客戶端程序通過改變傳入的配置信息能夠改變使用的MapReduce目標。實際上,基于Yarn的MapReduce正是以這種方式被客戶端程序訪問的。