MapReduce--实现WordCount

MapReduce实现WordCount

1、需求

  • 基于MapReduce开发实现对文件中的单词进行统计,统计每个单词出现的次数
  • 将程序写好以后,打成jar包,上传到Linux中,提交给YARN运行

2、分析

Input:

  • /wordcount/input/wordcount.txt
  • 将每一行数据变成一个keyvalue
  • value就是这一行的内容

Map:

  • 将value进行分割,得到每个单词,将单词作为key,1作为value输出

Shuffle:

  • 分组:按照单词做分组,相同单词的value都在一个迭代器中
  • 排序:按照单词做排序

Reduce

  • 对每个单词的迭代器中进行聚合

Output:/wordcount/output4

3、代码实现

创建一个子模块,导入Maven依赖
注意:如果apache版本依赖下载不下来,建议你可以从别的人那拷贝一份本地库,覆盖自己的本地库

  • Driver类
package bigdata.hanjiaxiaozhi.cn.mapreduce.wc;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;/**
 * @ClassName WordCountDriver
 * @Description TODO 实现Wordcount程序的Driver类
 * 1-包含程序的入口,main
 * 2-必须构建一个 MapReduce的job,配置job,提交运行job
 * @Date 2020/5/29 15:29
 * @Create By     hanjiaxiaozhi
 */
public class WordCountDriver extends Configured implements Tool {
​
    /**
     *-必须构建一个 MapReduce的job,配置job,提交运行job
     * @param args
     * @return
     * @throws Exception
     */
    @Override
    public int run(String[] args) throws Exception {
        //todo:1-构建一个MapReduce的job对象
        Job job = Job.getInstance(this.getConf(),"userwc");//第一个参数是conf对象,第二个程序的名字
        //设置可运行的类
        job.setJarByClass(WordCountDriver.class);//todo:2-配置这个job的五个阶段
        //配置输入
        Path inputPath = new Path(args[0]);//这里不写死,通过参数的形式来传递,用程序的第一个参数来代表输入的路径
        TextInputFormat.setInputPaths(job,inputPath);//为当前job设置输入读取的HDFS的路径
        //配置Map
        job.setMapperClass(WordCountMapper.class);//指定Mapper的类
        job.setMapOutputKeyClass(Text.class);//指定Map输出的key的类型
        job.setMapOutputValueClass(IntWritable.class);//指定Map输出的Value的类型//配置shuffle:Shuffle我们不干预,使用默认的//配置reduce
        job.setReducerClass(WordCountReducer.class);//指定Reduce的类
        job.setOutputKeyClass(Text.class);//指定Reduce输出的key的类型
        job.setOutputValueClass(IntWritable.class);//指定Reduce输出的Value的类型//配置输出
        Path outputPath = new Path(args[1]);//这里不写死,通过参数的形式来传递,用程序的第二个参数来代表输出的路径
        TextOutputFormat.setOutputPath(job,outputPath);//为当前的job设置输出的路径,结果保存的路径//todo:3-提交这个job的运行
        return job.waitForCompletion(true) ? 0 : -1;
    }
​
    /**
     * 负责调用run方法
     * @param args
     */
    public static void main(String[] args) throws Exception {
        //第一个参数:Configuration对象,所有Hadoop程序都需要的
        Configuration conf = new Configuration();
        //第二个参数:tool对象,你要调用哪个对象的run方法
        //第三个参数:将args数组传递过去
        int status = ToolRunner.run(conf, new WordCountDriver(), args);
        //在run方法中会提交程序运行,返回运行的结果,如果运行结果为0.就正常退出
        System.exit(status);
    }
​
}
​
  • Mapper类
package bigdata.hanjiaxiaozhi.cn.mapreduce.wc;import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException;/**
 * KEYIN, VALUEIN, KEYOUT, VALUEOUT
 * Map输入的Key和Value类型
 * Map输出的Key和Value类型
 *
 * @ClassName WordCountMapper
 * @Description TODO 现Wordcount程序的Mapper类
 * @Date 2020/5/29 15:48
 * @Create By     hanjiaxiaozhi
 */
public class WordCountMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
​
    //定义输出的Key
    Text outputKey = new Text();
    //定义输出的Value
    IntWritable outputValue = new IntWritable(1);
​
​
    /**
     * Input阶段传递进来的每一个KeyValue都会调用一次map方法
     * @param key:这条数据中的key:行的偏移量
     * @param value:这条数据中的value:行的内容
     * @param context:上下文对象 ,用于输出的
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        //对这一行的内容,进行分割,得到每个单词
        String[] words = value.toString().split(" ");
        //遍历得到每个单词
        for (String word : words) {
            //将单词封装成Key
            this.outputKey.set(word);
            //输出这个单词和1
            context.write(this.outputKey,this.outputValue);
        }
    }
}

  • Reducer类
package bigdata.hanjiaxiaozhi.cn.mapreduce.wc;import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException;/**
 * KEYIN,VALUEIN,KEYOUT,VALUEOUT
 * Reduce输入的Key和Value类型 = Map阶段输出的Key和Value的类型
 * Reduce输出的Key和Value类型 = 最后结果的类型
 * @ClassName WordCountReducer
 * @Description TODO 实现Wordcount程序的MReducer类
 * @Date 2020/5/29 16:09
 * @Create By     hanjiaxiaozhi
 */
public class WordCountReducer extends Reducer<Text,IntWritable,Text,IntWritable> {
​
    IntWritable outputValue = new IntWritable();/**
     * shuffle输出的每一个KeyValue都会调用一次reduce方法
     * @param key:shuffle分组排序以后的每个key
     * @param values:这个key对应的value的迭代器结合
     * @param context
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        int sum = 0;
        //从迭代器中取出这个key的每一个value
        for (IntWritable value : values) {
            sum += value.get();
        }
        //key不变,sum作为新的value输出
        this.outputValue.set(sum);
        context.write(key,this.outputValue);
    }
}

4、提交运行

  • 打成jar包
  • 提交yarn集群运行
    上传
    在这里插入图片描述
    运行
yarn jar /export/datas/wc.jar bigdata.hanjiaxiaozhi.cn.mapreduce.wc.WordCountDriver /wordcount/input/wordcount.txt /wordcount/output4

5、总结

  • 开发一个MapReduce程序
  • Driver:负责构建一个job,定义五个阶段,提交job运行
  • Mapper:负责重写map方法
  • Reducer:负责重写reduce方法
WordCountMapReduce中最基本的程序之一,它用于计算文本中每个单词的出现次数。下面是WordCount的Java代码: ```java import java.io.IOException; import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class WordCount { public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable>{ private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(Object key, Text value, Context context) throws IOException, InterruptedException { StringTokenizer itr = new StringTokenizer(value.toString()); while (itr.hasMoreTokens()) { word.set(itr.nextToken()); context.write(word, one); } } } public static class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable> { private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); } result.set(sum); context.write(key, result); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "word count"); job.setJarByClass(WordCount.class); job.setMapperClass(TokenizerMapper.class); job.setCombinerClass(IntSumReducer.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } } ``` 这个程序的输入是一个文本文件,输出是每个单词出现的次数。在运行之前,你需要安装Hadoop并将输入文件放入HDFS。运行MapReduce程序的命令如下: ``` hadoop jar WordCount.jar WordCount /input /output ``` 其中,WordCount.jar是你打包好的Java程序,input是输入文件的路径,output是输出目录的路径。执行这个命令后,MapReduce作业就会在Hadoop集群上运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值