WordCount案例--mapreduce编写(mr类型、map方法、reduce方法、Job方法) 详细注解

按我们上传一个文件,统计该文件里面的所有单词个数为例进行讲解

一、编程规范:

在这里插入图片描述

二、Mapper阶段业务逻辑实现

MyMapper类继承的Mapper方法的四个参数的类型解析:

1、KEYIN:表示数据输入的时候key数据类型,在默认的读取数据组件下,叫InputFormat,它的行为是一行一行读取待处理的数据,读取一行,返回一行给我们的mr程序,在这种情况下,keyin就表示一行的起始偏移量  因始数据的类型是long
2、VALUEIN:表述数据输入的时候value的数据类型,在默认的读取数据组件下 valuein就表示读取的这一行内容 因始读取的数据类型是String  
3、KEYOUT:表示mapper数据输出的时候key的数据类型,在本案例当中,输出的key是单词,因始类型是String
4、VALUEOUT表示mapper 数据输出的时候value的数据类型 在本案例当中,输出的key是单词的次数,因此数据类型是Integer
public class MyMapper extends Mapper<keyin, valuein, keyout, valueout>

这里所说的数据类型long、String都是jdk自带的类型,在序列化的时候,效率低下,因此hadoop自己封装一套数据类型,如下:

long---->LongWritable
String---->Text
Integer---->Intwritable
null-->NullWritable

//上面已经解析为啥使用LongWritable、Text、IntWritable
public class MyMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
//这里就是mapreduce程序,mapper阶段业务逻辑实现方法,该方法的调用取决于读取数据的组件有没有给Mr传入数据,如果有,每传入一个《k,v》对  该方法就调用一次
//这里LongWritable key 表示传入的keyin 类型是LongWritable
//Text value 表示传入的valuein 类型是Text
   public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
    //拿到传入进来的一行内容,把数据类型转化为String
    String line=value.toString();
    //将这一行内容按照分隔符进行一行内容的切割, 切割成一个单词数组,这里是以空格分割
    String[] words=line.split(" ");
    //遍历数组,每出现一个单词 就标记一个数字1 <hello,1>
    for(String word : words){
      //使用mr程序的上下文Context 把 mapper 阶段处理的数据发送出去
      //作为reduce 节点的输入数据
      conetext.write(new Text(word),new IntWritable(1));
      //比如:hadoop hadoop spark<hadoop,1><hadoop,1><spark,1>
    }
 }

}

三、Reduce阶段业务逻辑实现

这里是MR程序,reducer阶段处理的类
MyReduce类继承的Reducer方法的四个参数的类型解析:

1、KEYIN:就是reducer阶段输入的数据key数据类型,对应mapper的输出key类型,在本例中就是单词 Text
2、VALUEIN:就是reducer阶段输入的数据value数据类型,对应mapper的输出value类型,在本例中就是单词 次数IntWritable
3、KEYOUT:就是reducer阶段输出的数据key数据类型,j就是单词 Text
4、VALUEOUT就是reducer阶段输出的数据value数据类型,在本例中就是单词 次数IntWritable
public class MyReducer extendsReducer<keyin, valuein, keyout, valueout>

public class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable> {


//reduce接收所有来自map阶段处理的数据之后,按照key的字典序进行排序

//按照key是否相同(这里是单词相同)作为一组去调用reduce方法
//本方法的key就是这一组相同kv对的共同key
//把这一组的所有v作为一个迭代器传入我们的reduce方法
  public void reduce(Text key, Iterable<IntWritable> values, Context context)
    throws IOException, InterruptedException {
    //定义一个计数器
    int count =0;
   //遍历一组迭代器, 把每一个数量1累加起来就构成一个单词的总次数
    for(IntWritable value:values){
       count +=value.get();
    }
//把最终的结果输出
   context.write(key,new IntWrtitable(count))
       
  }

 }

四、Driver阶段业务逻辑实现

这个类就是MR程序运行的时候的主类,本类组装了一些程序运行时候所需要的信息
比如:使用的就是那个Mapper类 那个Reducer类 输入数据在哪,输出数据在什么地方

public class MyDriver {

  public static void main(String[] args) throws Exception {
  //通过Job来封装本次mr的相关信息
   Configuration conf = new Configuration();
   Job job = Job.getInstance(conf, "JobName");
   //指定本次mr job jar 包运行主类
   job.setJarByClass(MyDriver.class);
   // 指定本次mr 所用mapper  类
   job.setMapperClass(MyMapper.class);
   //指定本次mr 所用reducer 类
   job.setReducerClass(MyReducer.class);

   // 指定本次mr mapper阶段的输出 k v 类型
   job.setMapOutputKeyClass(Text.class);
   job.setMapOutputValueClass(IntWritable.class);
   
   // 指定本次mr 最终输出 k v 类型
   job.setOutputKeyClass(Text.class);
   job.setOutputValueClass(IntWritable.class);
  
   //指定本次mr 输入的数据路径 和最终输出结果放在什么位置
   FileInputFormat.setInputPaths(job, new Path("hdfs://localhost:9000/WordCount/input"));
   FileOutputFormat.setOutputPath(job, new Path("hdfs://localhost:9000/WordCount/output"));

   // 提交程序,并且监控打印程序执行情况
   boolean b=job.waitForCompletion(true);
   System.exit(b?0:1);
  
  }

 }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章