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

二、程序员编写的代码

 (可以查看hadoop-examples-0.20.203.0.jar,里面也有一个类grep)

    我们做一个简单的分布式的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/目录 

        或者编译成jar包HadoopGrep.jar放入hadoop/build/classes/demo/hadoop/目录

        找一个比较大的xx.log文件放,然后运行

        bin/hadoop demo.hadoop.HadoopGrep  input   /tmp/out  "[a-b]"
        (jar包运行:bin/hadoop jar HadoopGrep.jar  HadoopGrep  input   /tmp/output  "[a-b]" )
        说明:
         input  为xx.log文件所在目录 
         /tmp/output为输出目录 
         "[a-b]"   grep的字符串 

        查看输出目录的结果,查看hadoop/logs/里的运行日志。  
        在重新运行前,先删掉输出目录。

  3.2 集群运行模式

    (查看集群配置:http://blog.csdn.net/hguisu/article/details/7237395)

      1 )执行bin/hadoop dfs 可以看到它所支持的文件操作指令。   

      2) 创建目录输入inpu:   
           $ bin/hadoop dfs -mkdir input    

      3)上传文件xx.log到指定目录 input :   
           $ bin/hadoop dfs -put xx.log input

       4 )  执行 bin/hadoop demo.hadoop.HadoopGrep input  output
             (jar包运行:bin/hadoop jar HadoopGrep.jar  HadoopGrep  input   /tmp/output  "[a-b]" )

       5 ) 查看输出文件:

           将输出文件从分布式文件系统拷贝到本地文件系统查看:
            $ bin/hadoop fs -get output output
            $ cat output/*

            或者
            在分布式文件系统上查看输出文件:
            $ bin/hadoop fs -cat output/*

            重新执行前,运行hadoop/bin/hadoop dfs -rm output删除output目录

       7.运行hadoop/bin/stop-all.sh 结束。

四、效率

    经测试,Hadoop并不是万用灵丹,很取决于文件的大小和数量,处理的复杂度以及群集机器的数量,相连的带宽,当以上四者并不大时,hadoop优势并不明显。
    比如,不用hadoop用java写的简单grep函数处理100M的log文件只要4秒,用了hadoop local的方式运行是14秒,用了hadoop单机集群的方式是30秒,用双机集群10M网口的话更慢,慢到不好意思说出来的地步。

转自:http://blog.csdn.net/hguisu/article/details/7239390

原创文章,作者:s19930811,如若转载,请注明出处:http://www.178linux.com/3106

(0)
s19930811s19930811
上一篇 2015-04-13 22:52
下一篇 2015-04-13 22:52

相关推荐

  • 文件搜索之find的使用

    一.find介绍:   find是Linxu中一个十分常用的文件查找工具,其工作原理是通过遍历启起始路径下文件层级结构完成的,其特点是查找速度慢,能做到实时查找和精确查找。 二.使用方法: find  start_path search_conditions  action 1.statr_path:所要查找的文件的起始位置,默…

    Linux干货 2016-11-01
  • 【26期】Linux第六周学习小总结

        时光匆匆,一周时光悠然而逝,带给我们的只有知识的充实,和每日强大的自信心,学习的日益深入,慢慢的然我们的思绪和状态带回高中时光,吃饭上课睡觉三点一线的生活,枯燥中透露出稍微的晨曦,让每个明天都充满着期待,那我们的本周的学习中磁盘管理算是占了很大的比重,毕竟关于磁盘的知识很是难理解,那我就把本周的知识回顾温习,同时分享给大家。 &n…

    2017-08-19
  • 0808文本处理作业

                           1 、删除/etc/grub2.conf 文件中所有以空白开头的行行首的空白字符。 答:sed  ‘@^[[:space]]\+@@’  /etc/grub2/cf…

    Linux干货 2016-08-11
  • OpenStack私有云部署

    前言 相信你一定对“云主机”一词并不陌生吧,通过在Web页面选择所需主机配置,即可快速定制一台属于自己的虚拟主机,并实现登陆操作,大大节省了物理资源。但这一过程是如何实现的呢?本文带来OpenStack Icehouse私有云实战部署。 OpenStack 简介 OpenStack是由网络主机服务商Rackspace和美国宇航局联合推出的一个开源项目,Ope…

    2016-12-19
  • Select、Case

    select循环与菜单 select循环主要用于创建菜单,按数字排序list指定的顺序排序,并列出在标准输出,利用PS3列出提示符进行输入选择 用法: select VARIABLE in list  do     循环体命令 done PS3提示语定义: 在脚本中脚本代码的第一…

    Linux干货 2016-08-21
  • 基于Corosync + Pacemaker+DRBD实现MySQL高可用集群

    前言 在众多的高可用集群解决方案中,除了Heartbeat之外,Corosync也能提供类似于Heartbeat一样的功能,而且目前RedHat官方提供的高可用集群解决方案的程序包都以Corosync为主,所以今后Corosync会逐渐取代Heartbeat。本文带来的是基于Corosync + Pacemaker+DRBD的MySQL高可用集群解决方案。 …

    Linux干货 2015-06-12