gembin

          OSGi, Eclipse Equinox, ECF, Virgo, Gemini, Apache Felix, Karaf, Aires, Camel, Eclipse RCP

          HBase, Hadoop, ZooKeeper, Cassandra

          Flex4, AS3, Swiz framework, GraniteDS, BlazeDS etc.

          There is nothing that software can't fix. Unfortunately, there is also nothing that software can't completely fuck up. That gap is called talent.

          About Me

           

          Hadoop--海量文件的分布式計算處理方案

          Hadoop--海量文件的分布式計算處理方案
           
          Hadoop 是Google MapReduce的一個Java實現。MapReduce是一種簡化的分布式編程模式,讓程序自動分布到一個由普通機器組成的超大集群上并發執行。就如同java程序員可以不考慮內存泄露一樣, MapReduce的run-time系統會解決輸入數據的分布細節,跨越機器集群的程序執行調度,處理機器的失效,并且管理機器之間的通訊請求。這樣的模式允許程序員可以不需要有什么并發處理或者分布式系統的經驗,就可以處理超大的分布式系統得資源。

              一、概論

              作為Hadoop程序員,他要做的事情就是:
              1、定義Mapper,處理輸入的Key-Value對,輸出中間結果。
              2、定義Reducer,可選,對中間結果進行規約,輸出最終結果。
              3、定義InputFormat 和OutputFormat,可選,InputFormat將每行輸入文件的內容轉換為Java類供Mapper函數使用,不定義時默認為String。
              4、定義main函數,在里面定義一個Job并運行它。
              

              然后的事情就交給系統了。
              1.基本概念:Hadoop的HDFS實現了google的GFS文件系統,NameNode作為文件系統的負責調度運行在master,DataNode運行在每個機器上。同時Hadoop實現了Google的MapReduce,JobTracker作為MapReduce的總調度運行在master,TaskTracker則運行在每個機器上執行Task。

              2.main()函數,創建JobConf,定義Mapper,Reducer,Input/OutputFormat 和輸入輸出文件目錄,最后把Job提交給JobTracker,等待Job結束。

              3.JobTracker,創建一個InputFormat的實例,調用它的getSplits()方法,把輸入目錄的文件拆分成FileSplist作為Mapper task 的輸入,生成Mapper task加入Queue。

              4.TaskTracker 向 JobTracker索求下一個Map/Reduce。
                
               Mapper Task先從InputFormat創建RecordReader,循環讀入FileSplits的內容生成Key與Value,傳給Mapper函數,處理完后中間結果寫成SequenceFile.
               Reducer Task 從運行Mapper的TaskTracker的Jetty上使用http協議獲取所需的中間內容(33%),Sort/Merge后(66%),執行Reducer函數,最后按照OutputFormat寫入結果目錄。 

                TaskTracker 每10秒向JobTracker報告一次運行情況,每完成一個Task10秒后,就會向JobTracker索求下一個Task。

                Nutch項目的全部數據處理都構建在Hadoop之上,詳見Scalable Computing with Hadoop


              二、程序員編寫的代碼

              我們做一個簡單的分布式的Grep,簡單對輸入文件進行逐行的正則匹配,如果符合就將該行打印到輸出文件。因為是簡單的全部輸出,所以我們只要寫Mapper函數,不用寫Reducer函數,也不用定義Input/Output Format。

          package  demo.hadoop

          public
             class  HadoopGrep {

           
           public   static   class  RegMapper  extends  MapReduceBase  implements  Mapper {

            
           private  Pattern pattern;

            
           public   void  configure(JobConf job) {
             pattern 
           =  Pattern.compile(job.get( " mapred.mapper.regex " ));
            }

            
           public   void  map(WritableComparable key, Writable value, OutputCollector output, Reporter reporter)
              
           throws  IOException {
             String text 
           =  ((Text) value).toString();
             Matcher matcher 
           =  pattern.matcher(text);
             
           if  (matcher.find()) {
              output.collect(key, value);
             }
            }
           }

           
           private  HadoopGrep () {
           } 
           //  singleton 

           
           public   static   void  main(String[] args)  throws  Exception {
            
            JobConf grepJob 
           =   new  JobConf(HadoopGrep. class );
            grepJob.setJobName(
           " grep-search " );
            grepJob.set(
           " mapred.mapper.regex " , args[ 2 ]);

            grepJob.setInputPath(
           new  Path(args[ 0 ]));
            grepJob.setOutputPath(
           new  Path(args[ 1 ]));
            grepJob.setMapperClass(RegMapper.
           class );
            grepJob.setReducerClass(IdentityReducer.
           class );
                
            JobClient.runJob(grepJob);
           }
          }

                  RegMapper類的configure()函數接受由main函數傳入的查找字符串,map() 函數進行正則匹配,key是行數,value是文件行的內容,符合的文件行放入中間結果。
                  main()函數定義由命令行參數傳入的輸入輸出目錄和匹配字符串,Mapper函數為RegMapper類,Reduce函數是什么都不做,直接把中間結果輸出到最終結果的的IdentityReducer類,運行Job。


                  整個代碼非常簡單,絲毫沒有分布式編程的任何細節。


                 三.運行Hadoop程序

                  Hadoop這方面的文檔寫得不全面,綜合參考GettingStartedWithHadoop 與Nutch Hadoop Tutorial 兩篇后,再碰了很多釘子才終于完整的跑起來了,記錄如下:      

          3.1 local運行模式

                 完全不進行任何分布式計算,不動用任何namenode,datanode的做法,適合一開始做調試代碼。
                 解壓hadoop,其中conf目錄是配置目錄,hadoop的配置文件在hadoop-default.xml,如果要修改配置,不是直接修改該文件,而是修改hadoop-site.xml,將該屬性在hadoop-site.xml里重新賦值。
                 hadoop-default.xml的默認配置已經是local運行,不用任何修改,配置目錄里唯一必須修改的是hadoop-env.sh 里JAVA_HOME的位置。


                 將編譯好的HadoopGrep與RegMapper.class 放入hadoop/build/classes/demo/hadoop/目錄 找一個比較大的log文件放入一個目錄,然后運行

                 hadoop / bin / hadoop demo.hadoop.HadoopGrep log文件所在目錄 任意的輸出目錄 grep的字符串 


               查看輸出目錄的結果,查看hadoop/logs/里的運行日志。  
               在重新運行前,先刪掉輸出目錄。
            

          3.2 單機集群運行模式 

                 現在來搞一下只有單機的集群.假設以完成3.1中的設置,本機名為hadoopserver
                 第1步.    然后修改hadoop-site.xml ,加入如下內容:

          < property > 
            
           < name > fs.default.name </ name > 
            
           < value > hadoopserver:9000 </ value > 
          </ property > 
          < property > 
            
           < name > mapred.job.tracker </ name > 
            
           < value > hadoopserver:9001 </ value > 
          </ property > 
          < property > 
            
           < name > dfs.replication </ name > 
            
           < value > 1 </ value > 
          </ property > 


              從此就將運行從local文件系統轉向了hadoop的hdfs系統,mapreduce的jobtracker也從local的進程內操作變成了分布式的任務系統,9000,9001兩個端口號是隨便選擇的兩個空余端口號。
            
            另外,如果你的/tmp目錄不夠大,可能還要修改hadoop.tmp.dir屬性。


            第2步. 增加ssh不輸入密碼即可登陸。

              因為Hadoop需要不用輸入密碼的ssh來進行調度,在不su的狀態下,在自己的home目錄運行ssh-keygen -t rsa ,然后一路回車生成密鑰,再進入.ssh目錄,cp id_rsa.pub authorized_keys
              詳細可以man 一下ssh, 此時執行ssh hadoopserver,不需要輸入任何密碼就能進入了。

            3.格式化namenode,執行
            bin/hadoop namenode -format

            4.啟動Hadoop
               執行hadoop/bin/start-all.sh, 在本機啟動namenode,datanode,jobtracker,tasktracker
            
            5.現在將待查找的log文件放入hdfs,。
               執行hadoop/bin/hadoop dfs 可以看到它所支持的文件操作指令。
               執行hadoop/bin/hadoop dfs put log文件所在目錄 in ,則log文件目錄已放入hdfs的/user/user-name/in 目錄中

            6.現在來執行Grep操作
                hadoop/bin/hadoop demo.hadoop.HadoopGrep in out
                查看hadoop/logs/里的運行日志,重新執行前。運行hadoop/bin/hadoop dfs rmr out 刪除out目錄。

            7.運行hadoop/bin/stop-all.sh 結束

            3.3 集群運行模式
            假設已執行完3.2的配置,假設第2臺機器名是hadoopserver2
            1.創建與hadoopserver同樣的執行用戶,將hadoop解壓到相同的目錄。

            2.同樣的修改haoop-env.sh中的JAVA_HOME 及修改與3.2同樣的hadoop-site.xml

            3. 將hadoopserver中的/home/username/.ssh/authorized_keys 復制到hadoopserver2,保證hadoopserver可以無需密碼登陸hadoopserver2
               scp /home/username/.ssh/authorized_keys  username@hadoopserver2:/home/username/.ssh/authorized_keys
           
            4.修改hadoop-server的hadoop/conf/slaves文件, 增加集群的節點,將localhost改為
              hadoop-server
              hadoop-server2

            5.在hadoop-server執行hadoop/bin/start-all.sh
             將會在hadoop-server啟動namenode,datanode,jobtracker,tasktracker
             在hadoop-server2啟動datanode 和tasktracker
            
            6.現在來執行Grep操作
               hadoop/bin/hadoop demo.hadoop.HadoopGrep in out
              重新執行前,運行hadoop/bin/hadoop dfs rmr out 刪除out目錄

            7.運行hadoop/bin/stop-all.sh 結束。
              

          四、效率

              經測試,Hadoop并不是萬用靈丹,很取決于文件的大小和數量,處理的復雜度以及群集機器的數量,相連的帶寬,當以上四者并不大時,hadoop優勢并不明顯。
              比如,不用hadoop用java寫的簡單grep函數處理100M的log文件只要4秒,用了hadoop local的方式運行是14秒,用了hadoop單機集群的方式是30秒,用雙機集群10M網口的話更慢,慢到不好意思說出來的地步。

          posted on 2007-09-21 10:57 gembin 閱讀(2297) 評論(3)  編輯  收藏

          評論

          # re: Hadoop--海量文件的分布式計算處理方案 2007-09-22 00:14 千里冰封

          很牛,都分布式了  回復  更多評論   

          # asdf 2008-04-29 17:02 sadf

          re: Hadoop--海量文件的分布式計算處理方案  回復  更多評論   

          # asdf 2008-04-29 17:03 sadf

          <a href="fa q">Hadoop--海量文件的分布式計算處理方案</a>  回復  更多評論   


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          導航

          統計

          常用鏈接

          留言簿(6)

          隨筆分類(440)

          隨筆檔案(378)

          文章檔案(6)

          新聞檔案(1)

          相冊

          收藏夾(9)

          Adobe

          Android

          AS3

          Blog-Links

          Build

          Design Pattern

          Eclipse

          Favorite Links

          Flickr

          Game Dev

          HBase

          Identity Management

          IT resources

          JEE

          Language

          OpenID

          OSGi

          SOA

          Version Control

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          free counters
          主站蜘蛛池模板: 合肥市| 黎川县| 汤阴县| 平罗县| 桦南县| 滦南县| 辰溪县| 达日县| 涿鹿县| 招远市| 南江县| 托克逊县| 张家口市| 仪征市| 海盐县| 如皋市| 淮南市| 旌德县| 丰镇市| 西藏| 苗栗市| 阜城县| 清水县| 黄梅县| 连江县| 拜城县| 韶山市| 珲春市| 花莲市| 武宣县| 高阳县| 常德市| 车险| 乐陵市| 榆中县| 阿拉善左旗| 新宁县| 神木县| 阿图什市| 北安市| 克山县|