MapReduce概述和编写简单案例-01

案例实操wordcount案例,统计单词出现次数

编码先导入hadoop依赖包,下面这个路径里有详细操作步骤

https://blog.csdn.net/kxj19980524/article/details/89043569

mapper阶段

Mapper<LongWritable, Text, Text, IntWritable>

mapper后面的这四个参数,就是输入key类型输入value类型,输出key类型,输出value类型

看上图,读取hello.txt数据的时候它是一行一行读的,key就是行号,value就是这一行的字符串,对照上面hadoop与java对应的数据类型,long对应的是LongWritable,String对应的text所以第一个参数是LongWritable,第二个参数为Text,看下面代码,mapper里做的工作是把每行的数据按空格进行分开,然后输出到缓冲区,没分出一个单词就输出一次,输出的key就是单词名,value就是1.有几个重复的单词就在缓冲区value的数组里加个1,可以把value看成是一个数组.

package com.buba.mapreduce.wordcount;

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:输入数据的key 文件的行号
 * 第二个参数   VALUEIN:每行的输入数据
 *
 * 第三个参数   KEYOUT:输出数据的key
 * 第四个参数   VALUEOUT:输出数据的value类型
 */
public class WordcountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {

    //hello world
    //hadoop spark
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        //1.获取这一行数据
        String line = value.toString();

        //2.获取每一个单词
        String[] words = line.split(" ");

        for(String word : words){
            System.out.println(word);
            //3.输出每一个单词
            context.write(new Text(word),new IntWritable(1));
        }
    }
}

在源码中可以看到,每次写出一条数据的时候都会在这判断是否有下一行,然后再进map方法 

 reduce阶段

reducer后面的四个参数跟上面同理,整个mapper阶段执行完后才执行reducer阶段.这里面的逻辑就是把mapper阶段拆开的单词数量进行累加然后输出出去.

package com.buba.mapreduce.wordcount;

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

import java.io.IOException;

public class WordcountReducer extends Reducer<Text, IntWritable,Text,IntWritable> {
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        //1.统计所有单词个数
        int count = 0;
        for(IntWritable value:values){
            System.out.println(key);
            System.out.println(value);
            count += value.get();
        }
        //2.输出所有单词个数
        context.write(key,new IntWritable(count));
    }
}

driver阶段

就是设置一些job的参数,这个mapreduce的各个参数. 

package com.buba.mapreduce.wordcount;

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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

//驱动主程序
public class WordcountDriver {

    public static void main(String[] args) throws Exception{
        //1.获取job对象信息  Configuration这个对面默认从本地获取,直接new对象就行不用添加参数
        Configuration configuration = new Configuration();

        Job job = Job.getInstance(configuration);

        //2.设置加载jar位置
        job.setJarByClass(WordcountDriver.class);

        //3.设置mapper和reducer的class类
        job.setMapperClass(WordcountMapper.class);

        job.setReducerClass(WordcountReducer.class);

        //4.设置输出mapper的数据类型
        job.setMapOutputKeyClass(Text.class);

        job.setMapOutputValueClass(IntWritable.class);

        //5.设置最终数据输出的类型
        job.setOutputKeyClass(Text.class);

        job.setOutputValueClass(IntWritable.class);

        //6.设置输入数据和输出数据路径
        FileInputFormat.setInputPaths(job,new Path(args[0]));

        FileOutputFormat.setOutputPath(job,new Path(args[1]));

        //7.提交
        boolean result = job.waitForCompletion(true);

        //如果成功返回0,失败返回1
        System.exit(result?0:1);
    }
}

另一种写法 

package com.buba.mapreduce.wordcount;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
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;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class WordcountDriver extends Configured implements Tool{

	public static void main(String[] args) throws Exception {
		WordcountDriver lc = new WordcountDriver();
    	int status = ToolRunner.run(lc.getConf(), lc, args);
    	System.exit(status);

	}
	
	 public int run(String[] args) throws Exception {
			//1.获取job对象信息  Configuration这个对面默认从本地获取,直接new对象就行不用添加参数
        Configuration configuration = new Configuration();

        Job job = Job.getInstance(configuration);

        //2.设置加载jar位置
        job.setJarByClass(WordcountDriver.class);

        //3.设置mapper和reducer的class类
        job.setMapperClass(WordcountMapper.class);

        job.setReducerClass(WordcountReducer.class);

        //4.设置输出mapper的数据类型
        job.setMapOutputKeyClass(Text.class);

        job.setMapOutputValueClass(IntWritable.class);

        //5.设置最终数据输出的类型
        job.setOutputKeyClass(Text.class);

        job.setOutputValueClass(IntWritable.class);

        //6.设置输入数据和输出数据路径
        FileInputFormat.setInputPaths(job,new Path(args[0]));

        FileOutputFormat.setOutputPath(job,new Path(args[1]));

        //7.提交
        boolean result = job.waitForCompletion(true);
	    	
	    	return result ? 0 : 1;
		}

}

 

 进行测试

测试1,在window测试,需要安装hadoop环境变量.把main方法添加两个参数,因为driver代码里调用了args数组里的两个值.这两个参数第一个是输入参数路径,就是源数据文件,第二个参数是mapreduce执行完后生成的文件路径地址,注意,这个路径不能存在,是执行完后自动生成的,如果这个文件本来就存在会报错.

放入一个log4j,要不然出不来日志

log4j.rootLogger=INFO, stdout  
log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n  
log4j.appender.logfile=org.apache.log4j.FileAppender  
log4j.appender.logfile.File=target/spring.log  
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout  
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n  

然后运行main方法,执行完后就在本地生成文件了,也可以使用debug方式运行,自己可以看看具体的运行流程.

测试2,在hadoop集群上进行测试.

把项目打成jar包,传到hadoop集群上去,如果使用的idea打的jar包,需要把jar包里的sf文件删掉

https://blog.csdn.net/kxj19980524/article/details/89070975   打jar包方式

上传到hadoop目录下,然后执行命令,首先得开启集群,后面两个参数是输入输出到hdfs上的路径.末三个参数是Driver的权限定类名.

 hadoop jar mapreduce.jar com.buba.mapreduce.wordcount.WordcountDriver /user/kxj/input /user/kxj/output

然后就可以查看了

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值