大数据入门(9)mapreduce计算wordcount的程序编写

版权声明: https://blog.csdn.net/u011518709/article/details/83894017

1、外部写好的程序打Java jar 包,导入jar
sftp> put e:/wc.jar

2、创建文本进行计算
vi words.log

hadoop fs -mkdir /wc
hadoop fs -mkdir /wc/srcData/

3、运行jar
hadoop jar wc.jar com.hadoop.mr.wordcount.WCRunner

hadoop jar wc.jar com.hadoop.mr.wordcount.WCRunner  /flow/data /flow/output

4、成功后查看文件:
 hadoop fs -ls /wc/output1

 hadoop fs -cat /wc/output1/part-r-00000

5、附程序源码:

A、WCMapper.java
package com.hadoop.mr.wordcount;

import java.io.IOException;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
//4个泛型中,前两个是指定mapper输入数据的类型,KEYIN是输入的key的类型,VALUEIN是输入的value的类型
//map 和 reduce 的数据输入输出都是以 key-value对的形式封装的
//默认情况下,框架传递给我们的mapper的输入数据中,key是要处理的文本中一行的起始偏移量,这一行的内容作为value
public class WCMapper extends Mapper<LongWritable, Text, Text, LongWritable>{

    //mapreduce框架每读一行数据就调用一次该方法
    protected void map(LongWritable key, Text value, Context context) throws IOException ,InterruptedException {
        //具体业务逻辑就写在这个方法体中,而且我们业务要处理的数据已经被框架传递进来,在方法的参数中 key-value
        //key 是这一行数据的起始偏移量     value 是这一行的文本内容
                
        //将这一行的内容转换成string类型
        String line = value.toString();
        
        //当前行按特定分隔符切分
        String[] words = StringUtils.split(line," ");
        
        //遍历输入kv形式
        for(String word:words){
            context.write(new Text(word),new LongWritable(1));
        }
        
    };
}

B、WCReduce.java

package com.hadoop.mr.wordcount;

import java.io.IOException;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class WCReduce extends Reducer<Text, LongWritable, Text, LongWritable>{

    //框架在map处理完成之后,将所有kv对缓存起来,进行分组,然后传递一个组<key,valus{}>,调用一次reduce方法
    //<hello,{1,1,1,1,1,1.....}>
    protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException ,InterruptedException {
        
        long count = 0;
        for (LongWritable value:values){
            count+=value.get();
        }
        
        context.write(key, new LongWritable(count));
    };
}

C、WCRunner.java

package com.hadoop.mr.wordcount;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;


/**
 * 用来描述一个特定的作业
 * 比如,该作业使用哪个类作为逻辑处理中的map,哪个作为reduce
 * 还可以指定该作业要处理的数据所在的路径
 * 还可以指定改作业输出的结果放到哪个路径
 *
 */
public class WCRunner {
    public static void main(String[] args) throws Exception{
        Configuration conf = new Configuration();
        Job wcjob = Job.getInstance(conf);
        
        //设置整个job所用的类所在的jar包
        wcjob.setJarByClass(WCRunner.class);
        //job使用的mapper和reducer的类
        wcjob.setMapperClass(WCMapper.class);
        wcjob.setReducerClass(WCReduce.class);
        
        //reduce的输出数据kv类型
        wcjob.setOutputKeyClass(Text.class);
        wcjob.setOutputValueClass(LongWritable.class);
        
        //mapper的输出数据kv类型
        wcjob.setMapOutputKeyClass(Text.class);
        wcjob.setMapOutputValueClass(LongWritable.class);
        
        //指定要处理的输入数据存放路径/输入存放路径
        FileInputFormat.setInputPaths(wcjob, new Path("hdfs://192.168.21.115:9000/wc/srcData/"));
        FileOutputFormat.setOutputPath(wcjob, new Path("hdfs://192.168.1.115:9000/wc/output1/"));
        
        //将job提交给集群运行 
        wcjob.waitForCompletion(true);
        
    }

}

6、原理

1.执行MR的命令:
    hadoop jar <jar在linux的路径> <main方法所在的类的全类名> <参数>
    例子:
    hadoop jar /root/wc1.jar cn.itcast.d3.hadoop.mr.WordCount hdfs://itcast:9000/words /out2

2.MR执行流程
    (1).客户端提交一个mr的jar包给JobClient(提交方式:hadoop jar ...)
    (2).JobClient通过RPC和JobTracker进行通信,返回一个存放jar包的地址(HDFS)和jobId
    (3).client将jar包写入到HDFS当中(path = hdfs上的地址 + jobId)
    (4).开始提交任务(任务的描述信息,不是jar, 包括jobid,jar存放的位置,配置信息等等)
    (5).JobTracker进行初始化任务
    (6).读取HDFS上的要处理的文件,开始计算输入分片,每一个分片对应一个MapperTask
    (7).TaskTracker通过心跳机制领取任务(任务的描述信息)
    (8).下载所需的jar,配置文件等
    (9).TaskTracker启动一个java child子进程,用来执行具体的任务(MapperTask或ReducerTask)
    (10).将结果写入到HDFS当中
 

猜你喜欢

转载自blog.csdn.net/u011518709/article/details/83894017