[[PageOutline]] = '''使用Eclipse !MapReduce 套件開發程式''' = = 一、準備 = * 系統 : * Ubuntu 8.10 * Hadoop 0.18.3 * 下載安裝方法於 2.2 說明 * 開發工具 : * Eclipse 3.2.2 || || 指令 || 註解 || || $ || apt-get install eclipse || 安裝eclipse || * java 6 || || 指令 || 註解 || || $ || sudo apt-get purge java-gcj-compat || 由於版權關係,ubuntu預設安裝的gcj為java的模擬軟體,請移除 || || $ || sudo apt-get install sun-java6-bin sun-java6-jdk sun-java6-jre sun-java6-plugin || 安裝 Sun版Java || * 設定環境變數 * 開啟bash.bashrc 貼上環境變數設定(sudo gedit /etc/bash.bashrc),在最後一行貼入下面內容 {{{ export JAVA_HOME=/usr/lib/jvm/java-6-sun export HADOOP_HOME=/opt/hadoop/ export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar }}} * 由前面設定後,環境參數如下表 || Name || Path || || Hadoop Home || /opt/hadoop/ || || Java Home || /usr/lib/jvm/java-6-sun || = 二、安裝與設定 Hadoop = Hadoop 是Apache所維護的自由軟體專案,而HDFS (Hadoop Distributed File System)是指Hadoop檔案系統,因此安裝的時候我們安裝配置了Hadoop專案,但操作時,尤其指Hadoop系統操作,我們會用HDFS來稱呼。因此,整個邏輯可以看成,我們在Linux系統內安裝配置了Hadoop,執行之後,它會產生一個新的分散式的磁碟系統,也就是HDFS,架構在Linux之內。由於是分散式系統,意味著他可以橫跨多台Linux所形成的叢集系統,並聯其磁碟空間。不過此篇的目的為撰寫MapReduce程式,所以在此示範的設定為HDFS運作於單一的本機系統內。 == 2.1 幫User產生ssh金鑰 == || || 指令 || 註解 || ||$|| ssh-keygen -t rsa -P "" || 產生免密碼的ssh金鑰 || ||$|| cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys || 匯入免檢查名單 || ||$|| ssh localhost || 測試登入是否不用密碼 || ||$|| exit || 完成離開 || == 2.2 安裝 Hadoop == || || 指令 || 註解 || || $ || wget http://ftp.twaren.net/Unix/Web/apache/hadoop/core/hadoop-0.18.3/hadoop-0.18.3.tar.gz || 下載原始碼 || || $ || sudo tar -zxvf hadoop-0.18.3.tar.gz -C /opt/ || 解壓縮 || || $ || sudo chown -R waue:waue /opt/hadoop-0.18.3 || 改權限 || || $ || sudo ln -sf /opt/hadoop-0.18.3 /opt/hadoop || 建目錄連結 || || $ || cd /opt/hadoop || || == 2.3 設定 == * 修改 hadoop-env.sh 檔 ($ gedit /opt/hadoop/conf/hadoop-env.sh ) * 修改內容: {{{ #!diff --- /opt/hadoop/conf/hadoop-env.sh.bek +++ /opt/hadoop/conf/hadoop-env.sh @@ -8,9 +8,12 @@ # The java implementation to use. Required. -# export JAVA_HOME=/usr/lib/j2sdk1.5-sun +export JAVA_HOME=/usr/lib/jvm/java-6-sun +export HADOOP_HOME=/opt/hadoop +export HADOOP_LOG_DIR=$HADOOP_HOME/logs +export HADOOP_SLAVES=$HADOOP_HOME/conf/slaves }}} * 修改 hadoop-site.xml 檔($ gedit HADOOP_HOME/conf/hadoop-site.xml) * 整段貼上: {{{ #!xml fs.default.name hdfs://localhost:9000/ mapred.job.tracker hdfs://localhost:9001/ mapred.map.tasks 1 define mapred.map tasks to be number of slave hosts mapred.reduce.tasks 1 define mapred.reduce tasks to be number of slave hosts dfs.replication 1 }}} == 2.4 啟動 HDFS == * 格式化HDFS (Hadoop Distributed File System) || || 指令 || || $ || cd $HADOOP_HOME || || $ || bin/hadoop namenode -format || * 執行結果: {{{ 09/02/03 18:08:59 INFO dfs.NameNode: STARTUP_MSG: /************************************************************ STARTUP_MSG: Starting NameNode STARTUP_MSG: host = vPro/140.110.138.193 STARTUP_MSG: args = [-format] STARTUP_MSG: version = 0.18.3 STARTUP_MSG: build = https://svn.apache.org/repos/asf/hadoop/core/branches/branch-0.18 -r 736250; compiled by 'ndaley' on Thu Jan 22 23:12:08 UTC 2009 ************************************************************/ 09/02/03 18:08:59 INFO fs.FSNamesystem: fsOwner=waue,waue,adm,dialout,cdrom,floppy,audio,dip,video,plugdev,fuse,lpadmin,admin,sambashare 09/02/03 18:08:59 INFO fs.FSNamesystem: supergroup=supergroup 09/02/03 18:08:59 INFO fs.FSNamesystem: isPermissionEnabled=true 09/02/03 18:08:59 INFO dfs.Storage: Image file of size 78 saved in 0 seconds. 09/02/03 18:08:59 INFO dfs.Storage: Storage directory /tmp/hadoop-waue/dfs/name has been successfully formatted. 09/02/03 18:08:59 INFO dfs.NameNode: SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down NameNode at vPro/140.110.138.193 ************************************************************/ }}} * 啟動HDFS || || 指令 || || $ || bin/start-all.sh || * 執行結果: {{{ starting namenode, logging to /opt/hadoop/logs/hadoop-waue-namenode-vPro.out localhost: starting datanode, logging to /opt/hadoop/logs/hadoop-waue-datanode-vPro.out localhost: starting secondarynamenode, logging to /opt/hadoop/logs/hadoop-waue-secondarynamenode-vPro.out starting jobtracker, logging to /opt/hadoop/logs/hadoop-waue-jobtracker-vPro.out localhost: starting tasktracker, logging to /opt/hadoop/logs/hadoop-waue-tasktracker-vPro.out }}} * 在瀏覽器URL列輸入以下三個網址,若都有畫面則成功啟動 || 網址 || 說明 || || http://localhost:50030 || Map/Reduce Administration || || http://localhost:50060 || Task Tracker !StatusTask Tracker Status || || http://localhost:50070 || !NameNode || == 2.5 除錯 == * 如果你的系統在啟動的時候有錯誤發生,則請停止Hadoop並完全移除Hadoop產生的中間資料,再重新開始 || || 指令 || || $ || cd $HADOOP_HOME || || $ || bin/stop-all.sh || || $ || rm -rf /tmp/* || || || 檢查 2.3 內容,重新執行2.4內容 || = 三、 Hadoop的Eclipse-Plugin安裝與操作 = Elipse是Sun公司所開發,是個很知名的Java程式語言開發程式,雖然Hadoop也是用java所開發,但要讓eclipse認得Hadoop的API、編譯器、並執行程式,需要調校的地方很多,步驟也很繁瑣。IBM發佈了一個Eclipse插件-IBM MapReduce Tools for Eclipse,通過該插件,開發者可以在Eclipse上創建MapReduce應用程序。以下我們就來示範如何安裝這個Hadoop的eclipse-plugin。 == 3.1 eclipse 3.3 以上版本(有bug) == * 安裝IBM !MapReduce tool || || 指令 || || $ || sudo cp /opt/hadoop-0.18.3/contrib/eclipse-plugin/hadoop-0.18.3-eclipse-plugin.jar /usr/lib/eclipse/plugins/ || ps : 上述的方法需eclipse 3.3 以上 搭配 hadoop 0.17 以上版本。 * 在系統視窗中,右鍵點選eclipse圖示,在指令欄加入參數以增加穩定度 {{{ /usr/bin/eclipse -vmargs -Xmx512M }}} * 啟動eclipse,從視窗介面操作: || 視窗操作 || 介面中設定 || 註解 || || '''File''' > '''New > Project''' || 看到 '''!MapReduce category''' || 檢查是否安裝IBM !MapReduce tool成功 || || '''Window''' > '''Preferences''' > '''java'''> '''compiler''' ||設定 '''compiler compliance level''' 為 1.6 || 更改java編譯器為1.6 以上,否則會出現一堆error|| * 開啟hadoop 專案 || 視窗操作 || 介面中設定 || 註解 || || '''File''' > '''new''' > '''Map/Reduce Project'''>'''next''' || '''Project name''':''sample'' [[br]] '''Configure Hadoop install directory''' => /opt/hadoop || 設定專案名稱及hadoop的家目錄 || * 完成後 Project Explorer可以看到 sample的專案列出 * 讓Eclipse連接到HDFS || 視窗操作 || 介面中設定 || 註解 || || '''Window''' > '''Show View''' > '''Other...''' > '''!MapReduce Tools''' || '''!MapReduce locations''' || 開啟MapReduce編譯環境,完成後右下方視窗會多一個藍色的大象圖示 || || 點選右下藍色大象圖示 || '''location name''' : ''test'' [[br]] '''Host''':''localhost'' [[br]] M/R Master: '''Port''':''9001'' [[br]] DFS Master: '''Use Use M/R Master host''':''V'' [[br]] '''Port''':''9000''|| 設定對應到 hadoop-site.xml檔 || * mapred.job.tracker 的設定若為 hdfs://ubuntu:9010/ ,則M/R Master的設定為 '''host:ubuntu''' , '''Port:9010''' ,DFS Master的設定則對應到 fs.default.name * 注意 hdfs必須已經啟動,否則無法點選finish鍵 * 完成後在Project Explorer可以看到'''DFS Locations'''出現 * 2009/2/5 測試到目前為止,用最新版的eclipse 3.4 搭配 0.18.3 或 0.19.0 版的 hadoop plugin,在"run as" => "run on hadoop" 都無法正常運作(應該要彈出選擇server location的視窗),此問題在2008/7/31就被發現並已被發佈於[http://webui.sourcelabs.com/hadoop/issues/3744 (HADOOP-3744) Eclipse Plugin does not work with Eclipse Ganymede (3.4)],目前尚待解決。 == 3.2 eclipse 3.2 以下版本 == * 安裝IBM !MapReduce tool eclipse 3.2 以前的版本必須要去IBM官方網站下載mapReduce_tools.zip,解壓縮後將資料夾複製到$eclipse/plugins/才可以運作 * 在系統視窗中,右鍵點選eclipse圖示,在指令欄加入參數以增加穩定度 {{{ /usr/bin/eclipse -vmargs -Xmx512m }}} * 啟動eclipse,從視窗介面操作: || 視窗操作 || 介面中設定 || 註解 || || '''File''' > '''New > Project''' || 看到 '''!MapReduce category''' || 檢查是否安裝IBM !MapReduce tool成功 || || '''Window''' > '''Preferences''' > '''java'''> '''compiler''' ||設定 '''compiler compliance level''' 為 5.0 || 更改java編譯器為5.0以上,否則會出現一堆error|| * 啟動eclipse,從視窗介面操作 || 視窗操作 || 介面中設定 || 註解 || || '''File''' > '''new''' > '''project''' > '''map-reduce project''' > '''next''' > || '''project name''' : ''sample'' [[br]] '''use default location''' : V [[br]] '''use default Hadoop''' : V [[br]] > '''Finish''' [[br]] || 設定專案預設值 || * 讓Eclipse連接到HDFS || 視窗操作 || 介面中設定 || 註解 || || '''Window''' > '''Show View''' > '''Other...''' > '''!MapReduce Tools''' > '''!MapReduce Servers''' || '''!MapReduce Servers''' || 開啟MapReduce編譯環境,完成後右下方視窗會多一個藍色的大象圖示 || || 點選藍色大象圖示 || '''Server name''' : ''any_you_want'' [[br]] '''Hostname''' : ''localhost'' [[br]] '''Installation directory''': ''/opt/hadoop/'' [[br]] '''Username''' : ''waue'' [[br]] || 開啟Hadoop伺服器,若有任何的密碼提示對話框出現,請填入登入Linux的系統使用者之密碼 || = 四、用Eclipse編譯!MapReduce範例程式 = 在這個範例中,我們先上傳一個純文字檔到HDFS內,這個檔案的副檔名為何不重要,只要內文為純文字檔即可,簡單的可以直接把Readme檔上傳上去,但為了突顯MapReduce的威力,當然是放越大的檔案上去給Hadoop操一下越好囉!接著示範如何用Eclipse來編寫!MapReduce的程式,並執行編譯的動作。 '''1. 上傳字典檔,以供!WordCount程序作字數統計的來源檔''' || || 指令 || || $ || cd /opt/hadoop/ || || $ || wget xxx/132.txt || || $ || bin/hadoop dfs -mkdir input || || $ || bin/hadoop dfs -put 132.txt input || || $ || bin/hadoop dfs -ls || {{{ Found 1 items /user/waue/input 2008-05-23 15:15 rwxr-xr-x waue supergroup }}} '''2. 在eclipse中新增程式碼''' 於Eclipse左邊的'''Project explorer'''內,我們可以看到剛剛設定的工作目錄'''sample'''。 我們新增一個範例程式: || 視窗操作 || 介面中設定 || 註解 || || '''Project explorer'''內,右鍵點選 '''sample'''> '''new''' > '''file''' || '''file name''' : !WordCount.java || 新增一個!WordCount.java檔案 || '''3. 撰寫程式''' 貼上 [raw-attachment:wiki:hadoop-sample-code:WordCount.java WordCount.java] 的內容。 '''4. 執行''' || 視窗操作 || 介面中設定 || 註解 || || '''Project explorer'''內,右鍵點選 '''!WordCount.java''' > '''run as ...''' > '''choose an existing server from the list below''' || '''finish''' || 執行!MapReduce || '''5. 執行畫面會出現在右下方的視窗:console ''' '''6. Hadoop的運算結果置於HDFS內的檔案中,要觀看結果內容,有以下三種方法 ''' * 用瀏覽器: 網址輸入 http://localhost:50070,點檔案目錄, * 直接用HDFS的指令秀出結果內容 * 用指令將輸出結果從HDFS內複製到本機資料夾內再觀看 '''7. 執行期間或執行結束,都可以到以下網址來看執行過程及結果 ''' || 網址 || 說明 || || http://localhost:50030 || hadoop-master || || http://localhost:50060 || hadoop-jobTracker || || http://localhost:50070 || hadoop-fileSystem || = 五、 用Eclipse製成可在Hadoop上運行MapReduce的jar檔 = 1. 開啟MapReduce 專案 || 視窗操作 || 介面中設定 || 註解 || || '''File''' > '''new''' > '''Map/Reduce Project'''>'''next''' || '''Project name''':''sample'' [[br]] '''Configure Hadoop install directory''': /opt/hadoop [[br]] => '''Finish''' || 完成會增加sample專案並切換成MapReduce的視野 || 2. 加入檔案WordCount.java檔 || 視窗操作 || 介面中設定 || 結果 || || 右鍵點選sample專案 > '''new''' > '''file''' || sample >'''src''' [[br]] '''File Name''': WordCount.java [[br]] => '''Finish''' || 完成後就多了一個WordCount.java檔 || 3. 寫入WordCount.java的內容([wiki:WordCount code]) 4. 執行 || 視窗操作 || 介面中設定 || 結果 || || '''run''' > '''Run Configurations...''' || '''Main''' tag :[[br]] '''Name''': '''WordCount''' [[br]] '''Project''': sample [[br]] '''Main class:''': WordCount ;'''Arguments''' tag : [[br]] '''Program arguments''': /opt/hadoop/log /opt/hadoop/test2 => '''Apply''' => '''Run''' || console 介面會出現執行結果 || * Eclipse是用模擬的方式模擬Hadoop的環境,執行這段程式碼,所以並沒有送上HDFS給Hadoop的job tracker作Map Reduce。http://localhost:50030 沒有工作運作的紀錄可以證明這點。 * 既然是在本機端上運作,所以給的Program arguments參數 '''/opt/hadoop/input /opt/hadoop/output''' 是本機上的目錄。 * 請確認 input 資料夾內有純文字資料,且output資料夾尚未存在(執行後系統會自行建立此資料夾並將結果放入) * 若Console 介面沒有錯誤訊息,則代表這段程式在主機端運作無誤 {{{ 09/02/06 17:18:35 INFO jvm.JvmMetrics: Initializing JVM Metrics with processName=JobTracker, sessionId= 09/02/06 17:18:35 WARN mapred.JobClient: Use GenericOptionsParser for parsing the arguments. Applications should implement Tool for the same. 09/02/06 17:18:35 WARN mapred.JobClient: No job jar file set. User classes may not be found. See JobConf(Class) or JobConf#setJar(String). 09/02/06 17:18:35 INFO mapred.FileInputFormat: Total input paths to process : 1 ... 略 ... 09/02/06 17:18:36 INFO mapred.JobClient: Map output bytes=445846 09/02/06 17:18:36 INFO mapred.JobClient: Map input bytes=320950 09/02/06 17:18:36 INFO mapred.JobClient: Combine input records=37943 09/02/06 17:18:36 INFO mapred.JobClient: Map output records=37943 09/02/06 17:18:36 INFO mapred.JobClient: Reduce input records=9284 }}} 錯誤排除 : * input 資料夾內有純文字資料 * output 資料夾尚未存在(執行後系統會自行建立此資料夾並將結果放入) * 檢查"run configuration" 內的 "Java Application" > "WordCount" 的設定是否正確 5. 打包成JAR || 視窗操作 || 介面中設定 || 結果 || || '''File''' > '''Export''' > Java > Runnable JAR file || ''' Launch configuration''' : '''WordCount - sample''' [[br]] '''Export destionation''' : /opt/hadoop/WordCount.jar => Finish => ok ||/opt/hadoop/下可以找到檔案WordCount.jar || * 最後一個ok在於包入Hadoop的必要library,所以匯出的WordCount.jar 檔大約有4.3MB 6. 運行WordCount於HDFS之上 指令: {{{ $ cd /opt/hadoop $ bin/hadoop jar WordCount.jar /user/waue/input /user/waue/out/ }}} * bin/hadoop jar 不可用 '''-jar''',但若是單純用java執行jar, 則要用'''$ java -jar XXX.jar''',不可只用jar * /user/waue/input /user/waue/out/ 為輸入和輸出的兩個參數,這兩個路徑是HDFS上得路徑,請確認hdfs內的/user/waue/input有純文字檔,且無/user/waue/out/這個資料夾。 * 若已經成功執行過,想再執行第二次,請更換output的資料夾名稱,否則會因資料夾已存在而出現錯誤訊息。 執行畫面 {{{ 09/02/06 18:13:14 WARN mapred.JobClient: Use GenericOptionsParser for parsing the arguments. Applications should implement Tool for the same. 09/02/06 18:13:14 INFO mapred.FileInputFormat: Total input paths to process : 1 09/02/06 18:13:14 INFO mapred.FileInputFormat: Total input paths to process : 1 09/02/06 18:13:15 INFO mapred.JobClient: Running job: job_200902051032_0009 09/02/06 18:13:16 INFO mapred.JobClient: map 0% reduce 0% 09/02/06 18:13:20 INFO mapred.JobClient: map 100% reduce 0% 09/02/06 18:13:23 INFO mapred.JobClient: Job complete: job_200902051032_0009 09/02/06 18:13:23 INFO mapred.JobClient: Counters: 16 09/02/06 18:13:23 INFO mapred.JobClient: File Systems 09/02/06 18:13:23 INFO mapred.JobClient: HDFS bytes read=320950 09/02/06 18:13:23 INFO mapred.JobClient: HDFS bytes written=130568 09/02/06 18:13:23 INFO mapred.JobClient: Local bytes read=168448 09/02/06 18:13:23 INFO mapred.JobClient: Local bytes written=336932 09/02/06 18:13:23 INFO mapred.JobClient: Job Counters 09/02/06 18:13:23 INFO mapred.JobClient: Launched reduce tasks=1 09/02/06 18:13:23 INFO mapred.JobClient: Launched map tasks=1 09/02/06 18:13:23 INFO mapred.JobClient: Data-local map tasks=1 09/02/06 18:13:23 INFO mapred.JobClient: Map-Reduce Framework 09/02/06 18:13:23 INFO mapred.JobClient: Reduce input groups=9284 09/02/06 18:13:23 INFO mapred.JobClient: Combine output records=18568 09/02/06 18:13:23 INFO mapred.JobClient: Map input records=7868 09/02/06 18:13:23 INFO mapred.JobClient: Reduce output records=9284 09/02/06 18:13:23 INFO mapred.JobClient: Map output bytes=445846 09/02/06 18:13:23 INFO mapred.JobClient: Map input bytes=320950 09/02/06 18:13:23 INFO mapred.JobClient: Combine input records=47227 09/02/06 18:13:23 INFO mapred.JobClient: Map output records=37943 09/02/06 18:13:23 INFO mapred.JobClient: Reduce input records=9284 }}} * http://localhost:50030 會紀錄剛剛運作的工作 = 六、 參考 = * NCHC Cloud Technique Develop Group * http://trac.nchc.org.tw/cloud/ * IBM Map-Reduce * http://www.alphaworks.ibm.com/tech/mapreducetools * Cloud9 * http://www.umiacs.umd.edu/~jimmylin/cloud9/umd-hadoop-dist/cloud9-docs/howto/start.html * Runing Hadoop * http://www.michael-noll.com/wiki/Running_Hadoop_On_Ubuntu_Linux_%28Single-Node_Cluster%29