大数据Hadoop(三)

大数据Hadoop(三)


MapReduce开发环境 (Maven )
  1. pom.xml

    <dependency>
          <groupId>org.apache.hadoop</groupId>
          <artifactId>hadoop-common</artifactId>
          <version>2.5.2</version>
    </dependency>
    <dependency>
          <groupId>org.apache.hadoop</groupId>
          <artifactId>hadoop-hdfs</artifactId>
          <version>2.5.2</version>
    </dependency>
    <dependency>
          <groupId>org.apache.hadoop</groupId>
          <artifactId>hadoop-client</artifactId>
          <version>2.5.2</version>
    </dependency>
    <dependency>
          <groupId>org.apache.hadoop</groupId>
          <artifactId>hadoop-mapreduce-client-core</artifactId>
          <version>2.5.2</version>
    </dependency>
    <dependency>
          <groupId>org.apache.hadoop</groupId>
          <artifactId>hadoop-yarn-common</artifactId>
          <version>2.5.2</version>
    </dependency>
    
  2. 代码结构 (骨架)

    /*1. Map*/
    public class MyMaper extends Mapper<LongWritable, Text, Text, IntWritable>{
           
            @Override
            protected void map(LongWritable k1, Text v1, Context context) throws IOException, InterruptedException {
                  //todo
                    }
    
            }
        }
    
    /*2. Reduce*/
    public class MyReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
            @Override
            protected void reduce(Text k2, Iterable<IntWritable> v2s, Context context) throws IOException, InterruptedException {
                //todo
            }
        }
    
    /*3. Job*/
            Configuration conf = new Configuration();
            Job job = Job.getInstance(conf, "MyFirstJob");
            //作业以jar包形式  运行
            job.setJarByClass(MyMapReduce.class);
    
            // InputFormat
            Path path = new Path("/src/data");
            TextInputFormat.addInputPath(job,path);
    
            //Map
            job.setMapperClass(MyMaper.class);
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(IntWritable.class);
    
            //shuffle 默认的方式处理 无需设置
    
            //reduce
            job.setReducerClass(MyReduce.class);
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(IntWritable.class);
    
            //输出目录一定不能存在,由MR动态创建
            Path out = new Path("/dest2");
            FileSystem fileSystem = FileSystem.get(conf);
            fileSystem.delete(out,true);
            TextOutputFormat.setOutputPath(job,out);
            //运行job作业
            job.waitForCompletion(true);
    
  3. MR运行

    必须运行在yarn集群上

    基于Maven构建工具,简化MR在yarn集群的运行

    <!--jar(main函数)   上传yarn 远程执行 bin/yarn jar xxx.jar -->
     <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-jar-plugin</artifactId>
             <version>2.3.2</version>
             <configuration>
               <outputDirectory>${basedir}</outputDirectory>
               <archive>
                 <manifest>
                   <mainClass>${baizhi-mainClass}</mainClass>
                 </manifest>
               </archive>
             </configuration>
      </plugin>
    
     <extensions>
          <extension>
            <groupId>org.apache.maven.wagon</groupId>
            <artifactId>wagon-ssh</artifactId>
            <version>2.8</version>
          </extension>
     </extensions>
    
     <plugin>
             <groupId>org.codehaus.mojo</groupId>
             <artifactId>wagon-maven-plugin</artifactId>
             <version>1.0</version>
             <configuration>
               <fromFile>${project.build.finalName}.jar</fromFile>
               <url>scp://root:123456@${target-host}${target-position}</url>
               <commands>
                 <command>pkill -f ${project.build.finalName}.jar</command>
                 <command>nohup /opt/install/hadoop-2.5.2/bin/yarn jar ${target-position}/${project.build.finalName}.jar > /root/nohup.out 2>&amp;1 &amp;</command>
               </commands>
               <!-- 显示运行命令的输出结果 -->
               <displayCommandOutputs>true</displayCommandOutputs>
             </configuration>
     </plugin>
    
    jar:jar wagon:upload wagon:sshexec
    
Maven自定义骨架

程序员根据自己的需求,定义Maven Archetype(骨架),后续选择自定义的骨架,就可以把我们需要的pom,其他配置文件,代码的骨架,自动生成,简化开发与测试

  1. 创建一个模板module

    1. 引入相关jar的坐标
    2. 创建Java代码
    
    在本项目的根下:mvn --settings F:\apache-maven-3.3.9\conf\settings.xml archetype:create-from-project
    

在这里插入图片描述
2. 复制骨架的坐标(便于后续的安装)

  ~~~markdown
  <groupId>com.baizhiedu</groupId>
  <artifactId>hadoop-test-archetype</artifactId>
  <version>1.0-SNAPSHOT</version>
  ~~~
  1. 安装骨架

    cd target\generated-sources\archetype
    mvn clean install
    
  2. 创建项目并引入骨架

    需要指定骨架的坐标,来源第二步。
    

在这里插入图片描述

MapReduce程序的调试
  1. 建议MR代码中通过Log4进行调试

    Logger logger = Logger(xxx.class);
    logger.info()
    
    通过上述操作 输出的结果,只能查看job的信息,而Map,Reduce的信息看不到。
    需要开启Yarn 历史日志 ,日志归档
    
  2. yarn集群中如何开启历史日志,日志归档

    1. 配置文件
       mapred-site.xml 历史服务
        <property>
            <name>mapreduce.jobhistory.address</name>
            <value>hadoop12:10020</value>
        </property>
         <property>
                <name>mapreduce.jobhistory.webapp.address</name>
                <value>hadoop12:19888</value>
         </property>
       yarn-site.xml 日志聚合
        <property>
            <name>yarn.log-aggregation-enable</name>
            <value>true</value>
        </property>
         <!--秒-->
         <property> 
             <name>yarn.log-aggregation.retain-seconds</name>
             <value>604800</value>
         </property>
    2. 启动进程
     sbin/mr-jobhistory-daemon.sh start historyserver
     sbin/mr-jobhistory-daemon.sh stop historyserver
    
  3. 实战
    应用shell脚本 解决

    1. 关闭日志聚合

    2. etc/hadoop/yarn-env.sh

      export YARN_LOG_DIR=~/logs/yarn
      export YARN_PID_DIR=~/data/yarn
      
    3. 创建脚本

      if [ $# -le 0 ]
      then
          echo 缺少参数
          exit 1
      fi
      
      logtype=out
      
      if [ $# -ge 1 ]
      then
          logtype=${2}
      fi 
      
      for n in `cat /opt/install/hadoop-2.5.2/etc/hadoop/slaves`
      do
          echo ===========查看节点 $n============
          ssh $n "cat ~/logs/yarn/userlogs/${1}/container_*/*${logtype}|grep hadoop"
      done
      
    4. 运行脚本

      1. 修改脚本权限
      2. ./scanMRLog.sh application_1558968514803_0001
      
MapReduce自定义数据类型
MapReduce中,Map与Reduce会进行跨JVM,跨服务器的通信,所以需要MapReduce中的数据类型进行序列化

Writable
Compareable

WriableCompareable (既能排序又能序列化)

IntWritable
LongWritable
FloatWritable
Text

NullWritable
#自定义hadoop的数据类型?
程序员自定义的类型 实现Writable Comparable(compareto方法 int 0  1 -1 )
直接实现WritableCompareble
write(DataOutput out)
readFields(DataInput in)
compareto()

equals
hashcode
toString


注意:自定义类型中 toString方法 返回的内容,将会位置输出文件的格式
MapReduce作业中Map,Reduce的一些细节问题
  1. MapReduce中是可以没有Reduce

    如果MapReduce中,只是对数据进行清洗,而不负责统计,去重的话,就没有Reduce

    job.setNumReduceTasks(0);
    //        job.setReducerClass(MyReducer.class);
    //        job.setOutputKeyClass(Text.class);
    //        job.setOutputValueClass(NullWritable.class);
    
  2. MapReduce中有多少个Map?

    1. 文本文件处理中,Map的数量由block决定。
    
  3. MapReduce中有多少个Reduce?

    1. Reduce个数可以设置的
       默认情况 reduce的个数是 1 
               mapreduce.job.reduces 1 
               
               job.setNumReduceTasks(?);
    
    1. 为什么要设置多个Reduce?
       提高MR的运行效率
    2. 多个Reduce的输出结果是多个文件,可以再次进行Map的处理,进行汇总
    3. Partion分区
       由分区决定Map输出结果,交给那个Reduce处理。默认有HashPartitioner实现
       k2.hashCode()%reduceNum(2) = 0,1 
    
  4. 程序员自定义分区算法

    /*123 R   大于3 在另一个Reduce */
    1. 自定义Partitioner
    public class MyPartitioner<k2,v2> extends Partitioner<k2,v2> {
        @Override
        public int getPartition(k2 key, v2 value, int numPartitions) {
    
            String k = key.toString();
    
            try{
                int key_i = Integer.parseInt(k);
                if(key_i<=3){
                    return 0;
                }else{
                    return 1;
                }
            }catch(Exception e){
                return -1;
            }
        }
    
    
    }
    2. job作业设置
     job.setPartitionerClass(MyPartitioner.class);
    
  5. MapReduce中的技术器 Counter

    自己定义计数器  书写在Map或者Reduce
       context.getCounter("group-name","counter-name").increment(1);
       public enum MyCounter {
        MY_COUNTER
       }
       context.getCounter(MyCounter.MY_COUNTER).increment(1);
    
  6. Combiner

    Combiner是Map端的Reduce,提前Map端作合并,从而减少传输的数据,提高效率。
    默认情况是Combiner关闭
    job.setCombinerClass(MyReducer.class);
    
Job作业的原理分析
  1. InputFormat

    从HDFS读入数据,并把读入的数据封装Key Value (k1,v1)
    在这里插入图片描述

    // 负责从HDFS(DataNode)中 读入文件的数据
    
    // 把块的数据 封装 split中 保证2者 一一对应
    
    public abstract 
        List<InputSplit> getSplits(JobContext context
                                   ) throws IOException, InterruptedException;
    // 负责把数据封装成 K,V  RecordReader
    public abstract 
        RecordReader<K,V> createRecordReader(InputSplit split,
                                             TaskAttemptContext context
                                            ) throws IOException, 
                                                     InterruptedException;
    

在这里插入图片描述
2. shuffle
在这里插入图片描述
3. shuffle代码体现

String inpath = "/hw/data1";
String outpath = "/dest";

Configuration conf = new Configuration();
Job job = Job.getInstance(conf, MapReduceJobSubmiter.class.getName());
//作业以jar包形式  运行
job.setJarByClass(MapReduceJobSubmiter.class);

// InputFormat
Path path = new Path(inpath);
TextInputFormat.addInputPath(job,path);

//Map
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(NullWritable.class);

//shuffle阶段代码处理
job.setPartitionerClass(MyPartitioner.class);
//map 自定义数据类型 compareto()
job.setCombinerClass(MyReducer.class);
//分组排序
job.setGroupingComparatorClass();


//reduce
job.setNumReduceTasks(2);
job.setReducerClass(MyReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class);

//输出目录一定不能存在,由MR动态创建
Path out = new Path(outpath);
FileSystem fileSystem = FileSystem.get(conf);
fileSystem.delete(out,true);
TextOutputFormat.setOutputPath(job,out);
//运行job作业
job.waitForCompletion(true);
MapReduce (二次排序)
hadoop-mr-secondsort
1. 自定义Map的key
2. 自定义分组排序 (分组)
3. 自定义分区

在这里插入图片描述

回顾HDFS与MapReduce
  1. HDFS
    在这里插入图片描述

  2. MR

    1. 什么情况需要使用MR
       操作HDFS数据时需要使用MR 
    2. MR的主要作用
       统计,去重,排序,清洗
    

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1. 注意 MapReduce只能对Key作排序
2. 开发 (wordcount topn 二排)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值