WordCount(单词统计)
原理:如图
代码:
1.导入3个jar包:hadoop-common、hadoop-core、hadoop-client
2.Map阶段:
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
//继承Mapper类
/**
Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
*
* KEYIN:表示mapper数据输入的时候key的数据类型,在默认的读取数据组件下,叫InputFormat,它的行为是一行一行的读取待处理的数据
* 读取一行,返回一行给程序,这种情况下 keyin就表示每一行的起始偏移量 因此数据类型是Long,一般不改变它的类型
*
* VALUEIN:表述mapper数据输入的时候value的数据类型,在默认的读取数据组件下 valuein就表示读取的这一行内容 因此数据类型是String
*
* KEYOUT 表示mapper数据输出的时候key的数据类型 在本案例当中 输出的key是单词 因此数据类型是 String
*
* VALUEOUT表示mapper数据输出的时候value的数据类型 在本案例当中 输出的key是单词的次数 因此数据类型是 Integer
*
* 这里所说的数据类型String Long都是jdk自带的类型 在序列化的时候 效率低下 因此hadoop自己封装一套数据类型
* long---->LongWritable
* String-->Text
* Integer--->Intwritable
* null-->NullWritable
*
* 相互转化:以String为例
* String ——> Test new Test(word)
* Test ——> String word.toString()
*/
public class MyMapper extends Mapper<LongWritable,Text,Text,LongWriteable> {
public void map(LongWritable key,Text value,Context context) throws IOException, InterruptedException {
//value为传入的每一行文本
//按照空格分隔每行文本,变成单词数组
String[] word = value.toString().split(" ");
//遍历数组中的单词,每有一个单词就标记一个数字1
//通过context上下文将数据传递到shuffle阶段
for(String wd : word){
context.write(new Text(wd),new LongWritanble(1));
}
}
}
3.Reduce阶段
//继承Reducer类
/**
* Reducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
*
* KEYIN:就是reducer阶段输入的数据key类型,对应mapper的输出key类型 在本案例中 就是单词 Text
*
* VALUEIN就是reducer阶段输入的数据value类型,对应mapper的输出value类型 在本案例中 就是单词次数 IntWritable
* .
* KEYOUT就是reducer阶段输出的数据key类型 在本案例中 就是单词 Text
*
* VALUEOUTreducer阶段输出的数据value类型 在本案例中 就是单词的总次数 IntWritable
*/
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class MyReduce extends Reducer<Text,LongWritable,Text,LongWritable>{
public void reduce(Text key,iterable<LongWritable> values,Context context) throws IOException, InterruptedException{
long count = 0;
//遍历,将同一个词的个数相加
for(LongWritable value:values){
//get()方法将LongWritable变为long类型
count += value.get();
}
context.write(key,new Writable(count));
}
}
4.整合
import com.bdqn.wc.MyDriver;
import com.bdqn.wc.MyMapper;
import com.bdqn.wc.Myreduce;
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;
import java.io.IOException;
public class MyDriver {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration();
//准备一个空任务
Job job = Job.getInstance(conf,"wc");
//设置任务主启动类
job.setJarByClass(MyDriver.class);
//设置任务的输入数据源
FileInputFormat.addInputPath(job,new Path("d:/abc.txt"));
//设置Mapper任务
job.setMapperClass(MyMapper.class);
//设置Mapper任务类的输出类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
//设置Reduce任务类
job.setReducerClass(Myreduce.class);
//设置Reduce任务类的输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
//设置任务的输出数据目标(生成的是fff文件夹)
FileOutputFormat.setOutputPath(job,new Path("d:/fff"));
//提交程序 并且监控打印程序的执行情况、
//只有job.waitForCompletion也可以
boolean b = job.waitForCompletion(true);
System.exit(b?0:1);
}
}
window下运行结果:
注:在window下运行要先安装Hadoop