文 / vincentzh
原文連接:http://www.cnblogs.com/vincentzh/p/6055850.html
上周末本來要寫這篇的,結果沒想到上周末自己環境都沒有搭起來,運行起來有問題的呢,拖到周一才將問題解決掉。剛好這周也將之前看的內容復習了下,邊復習邊碼代碼理解,印象倒是很深刻,對看過的東西理解也更深入了。
目錄
1、概述
Hadoop提供了Java的API用於處理程序的開發及,同樣的,通過在本地搭建熟悉的 eclipse 開發環境也能夠方便大型程序的開發與調試,完成的代碼無需部署,通過eclipse就能執行並輸出結果,通過抽樣數據的處理結果查看方便調試與驗證數據處理邏輯。代碼處理邏輯驗證無誤后,即可將所有程序打包上傳至集群,進行全集數據的處理工作。
在搭建開發環境之前,需要部署好自己的Hadoop環境,這樣做起來才會比較真實,並且集群的調度及參數配置也是與大型集群的配置維護幾乎沒什么差別(Hadoop環境的搭建詳見:Hadoop單機/偽分布部署、Hadoop集群/分布式部署)。
一般通過單機單機和偽分布環境來開發和調試程序,在單機環境下使用的是本地的文件系統,能夠利用 linux 命令方便獲取和查看代碼的執行結果,相反,在偽分布和集群環境上,代碼直接從HDFS讀取並輸出數據,相較於本地環境需要將數據在本地和HDFS之間 put/get ,麻煩不少,開發調試程序過程都使用的是數據的抽樣,否則代碼執行一次的時間過長,在單機和偽分布環境驗證無誤后才會將代碼部署上集群進行全集數據的處理。LZ在虛擬上部署了兩套環境,一個是偽分布環境、另一個是一個小的集群,當然單機/偽分布/集群之間可以互相切換,但自己部署的環境,為了互相切換麻煩,就干脆兩套環境都搭了起來,需要再那個環境執行,直接通過開發環境進行連接切換即可。
2、環境准備
1)配置集群並啟動所有守護進程,集群搭建見:Hadoop單機/偽分布部署、Hadoop集群/分布式部署。
2)安裝eclipse,本地安裝與集群上同一版本的 JDK 和 HADOOP。
3、配置插件
下載 Hadoop2.x-eclipse-plugin.jar,將其放入 eclipse 的 \plugins 目錄,並重啟 eclipse,在 Windows—>Show View—>Other 將會看到有 Map/Reduce 視圖,同時左側工程空間出現 DFS Locations 類似文件夾的東西。
4、配置文件系統連接
切換至 Map/Reduce 視圖,進行配置。
在這里的配置需要注意,要與自己集群上的 core-site.xml 配置文件中的配置一致。附上LZ配置文件的配置。當然有人在 Host 中直接寫的主機名,但要主義主機名與IP的映射關系是直接寫在HADOOP環境中的,這里的本地環境根本無法解析你寫進去的‘master’或者‘hadoop’之類的主機名稱,最簡單直接的就是用IP去配置,core-site.xml 配置文件中也使用 IP 進行配置。

5、測試連接
配置完成測試連接,需要確認所有守護進程啟動無誤。
6、代碼編寫與執行
測試代碼可以自己嘗試去寫,如果只是過過環境搭建成功的癮,就去官網直接拿吧。鏈接在這里。
當你需要編寫代碼或 copy 代碼時又會遇到這樣的問題,工程工作區為何沒有 MapReduce 開發相關的包呢,MapReduce 開發的包要去哪里找呢,就在這里。
代碼測試之前,新建的工程中並沒有 MapReduce 開發需要使用到的相關 jar 包,這就是前面提到的需要在 Windows 本地安裝同樣版本 Hadoop 的原因了,這里會用到其安裝目錄中開發編譯 MapReduce 程序時需要的 jar 包。在 Windows—>Preferences—>Hadoop Map/Reduce 中設置 Windows 本地安裝的Hadoop路徑(如:E:\ProgramPrivate\hadoop-2.6.0),設置完成再去創建 Hadoop 工程時會自動導入 Hadoop 相關的 jar 包。
我就貼個通過 API 提供的一些常用的基本實現類去實現的 WordCount 代碼吧,具體的參數配置可以參考。
1 package com.cnblogs.vincentzh.hadooptest; 2 3 import java.io.IOException; 4 5 import org.apache.hadoop.conf.Configuration; 6 import org.apache.hadoop.fs.Path; 7 import org.apache.hadoop.io.LongWritable; 8 import org.apache.hadoop.io.Text; 9 import org.apache.hadoop.mapred.FileInputFormat; 10 import org.apache.hadoop.mapred.FileOutputFormat; 11 import org.apache.hadoop.mapred.JobClient; 12 import org.apache.hadoop.mapred.JobConf; 13 import org.apache.hadoop.mapred.lib.LongSumReducer; 14 import org.apache.hadoop.mapred.lib.TokenCountMapper; 15 16 // 通過 Hadoop API 提供的基本實現類實現 WordCount 17 public class WordCount2 18 { 19 public static void main(String[] args) 20 { 21 //JobClient client = new JobClient(); 22 Configuration conf = new Configuration(); 23 JobConf jobConf = new JobConf(conf); 24 25 jobConf.setJobName("WordCount2"); 26 Path in = new Path("hdfs://192.168.1.110:9000/user/hadoop/input"); 27 Path out = new Path("hdfs://192.168.1.110:9000/user/hadoop/output"); 28 FileInputFormat.addInputPath(jobConf, in); 29 FileOutputFormat.setOutputPath(jobConf, out); 30 jobConf.setMapperClass(TokenCountMapper.class); 31 jobConf.setCombinerClass(LongSumReducer.class); 32 jobConf.setReducerClass(LongSumReducer.class); 33 jobConf.setOutputKeyClass(Text.class); 34 jobConf.setOutputValueClass(LongWritable.class); 35 36 //client.setConf(jobConf); 37 try 38 { 39 JobClient.runJob(jobConf); 40 } 41 catch (IOException e) 42 { 43 e.printStackTrace(); 44 } 45 } 46 }
執行完成,會有相應的作業執行統計信息輸出,Refresh 文件夾后會在左側 DFS 文件系統中看到輸出的文件。
7、問題梳理
運行時可能會出現不少問題,在這里只羅列下LZ遇到過的問題和解決的方法,沒遇到的自然也談不上和路人分享了。
7.1 console 無日志輸出問題
在 eclipse 執行 MapReduce 程序時會出現程序控制台無任何輸出信息的問題,沒有日志信息,沒有執行信息,無法知道程序執行的結果如何。
原因:console無日志輸出是因為在 project 中沒有進行 log 配置。
解決方案:直接將 hadoop 配置文件目錄($HADOOP_HOME/etc/hadoop/)下的 log4j.properties 文件 copy 進工程中即可。
7.2 權限問題
在 eclipse 執行 MapReduce 程序報錯,錯誤信息類似:org.apache.hadoop.security.AccessControlException:org.apache.hadoop.security.AccessControlException: Permission denied:user=john, access=WRITE, inode="input":hadoop:supergroup:rwxr-xr-x...
原因:Hadoop 上的 HDFS 只有部署環境時的用戶才有讀寫權限,大多數人應該都使用的是 ‘hadoop’ 吧,而我們的開發環境是在 Windows 本地進行搭建的,執行程序的時候是直接用本地的用戶進行作業的提交和執行,Hadoop 在提交作業和執行作業時需要對提交的用戶進行權限認證,自然 Windows 上的用戶並沒有讀寫 HDFS 文件和提交並執行作業的權利了。
解決方案:在 mapred-site.xml 配置文件中設置屬性 dfs.permission 為 false 即可。