1.需求:统计单词(以空格拆分)出现的次数
2.数据
歌名 像我这样的人
演唱 毛不易
作词 毛不易
作曲 毛不易
像 我 这样 优秀 的 人
本该 灿烂 过 一生
怎么 二十 多年 到头 来
还在 人海 里 浮沉
像 我 这样 聪明 的 人
早就 告别 了 单纯
怎么 还是 用了 一段 情
去 换 一身 伤痕
像 我 这样 迷茫 的 人
像 我 这样 寻找 的 人
像 我 这样 碌碌无为 的 人
你 还 见过 多少 人
像 我 这样 庸俗 的 人
从不 喜欢 装 深沉
怎么 偶尔 听到 老歌 时
忽然 也 晃 了 神
像 我 这样 懦弱 的人
凡事 都要 留 几分
怎么 曾经 也会 为了 谁
想过 奋不顾身
像 我 这样 迷茫 的 人
像 我 这样 寻找 的 人
像 我 这样 碌碌无为 的 人
你 还 见过 多少 人
像 我 这样 孤单 的 人
像 我 这样 傻 的 人
像 我 这样 不甘平凡 的 人
世界 上 有 多少 人
像 我 这样 莫名其妙 的 人
会不会 有人 心疼
3.加入jar包,当然如果你不知道需要哪些具体的jar,可直接将所有的jar包都扔进去
4.Mapper类
package com.w4xj.mapreduce.test.wordcount;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
/**
* Mapper类
* 继承import org.apache.hadoop.mapreduce.Mapper 类而不是org.apache.hadoop.mapred.Mapper接口,重写map方法
* Mapper类的泛型:LongWritable, Text, Text, IntWritable依次表示
* 输入的key LongWritable 行号
* 输入的value Text 一行内容
* 输出的key Text 单词
* 输出的value IntWritable 单词个数
* 注意:Mapper类的输出类型对应Reducer的输入类型
* @author w4xj
* @date 2019年3月10日 09:50:16
*
*/
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
//输出类型key
Text k = new Text();
//输出类型value
IntWritable v = new IntWritable(1);
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
//获取一行
String values = value.toString();
//切割
String[] fields = values.split(" ");
//输出
for (String field : fields) {
k.set(field);
//按输出类型写出
context.write(k, v);
}
}
}
5.Reducer类
package com.w4xj.mapreduce.test.wordcount;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
/**
* Reducer类
* 继承org.apache.hadoop.mapreduce.Reducer类,重写reduce方法
* Reducer类的泛型:LongWritable, Text, Text, IntWritable也同样依次表示
* 输入的key类型,输入的value类型,输出的key类型,输出的value类型
* @author w4xj
* @date 2019年3月10日 09:57:16
*/
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
/**
* Reducer默认把相同key分为一组,然后将value放到一个迭代器里
* 在reduce方法中进行业务操作
*/
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
//计数
int sum = 0;
//遍历迭代器,获取单词个数累加
for (IntWritable value : values) {
sum += value.get();
}
//输出
context.write(key, new IntWritable(sum));
}
}
6.Driver类
package com.w4xj.mapreduce.test.wordcount;
import java.io.IOException;
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;
/**
* Driver类,不需要继承类或者实现接口
* @author w4xj
* @date 2019年3月10日 10:11:13
*/
public class WordCountDriver {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
// 获取配置信息
Configuration conf = new Configuration();
// 获取任务实例
Job job = Job.getInstance(conf);
//设置jar包加载路径
job.setJarByClass(WordCountDriver.class);
//设置 map 和 Reduce 类
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);
//设置map类输出类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
//设置reduce输出类型(实际也是job的输出)
job.setOutputKeyClass(Text.class);
job.setOutputKeyClass(IntWritable.class);
//设置输入输出路径,多处输入一处输出
FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
//提交,获得执行返回结果,执行成功返回true
boolean result = job.waitForCompletion(true);
//退出
System.exit(result ? 0 : 1);
}
}
7.运行,因为这里设置的输入输出地址是main函数的输入参数,所以这里用run configurations这种方式(也可硬编码在代码中),填入输入输出路径G:/tempDir/wordcount_input G:/tempDir/wordcount_output,运行
8.结果是乱码,这是因为Hadoop在设计编码的时候,是写死的。默认是UTF-8,所以当你处理的文件编码格式不是为UTF-8的时候,比如为GBK格式,那么就会输出的时候就会出现乱码。
9.修改文件编码格式为utf8,这里用的是notpad++
10.删掉之前的输出路径,输出路径必须在程序运行前不存在,再次运行
11.在开发环境调试称为为本地模式,集群模式则需要将程序打成jar包放在集群中运行
12.项目右键-->export-->java-->jar file-->选择项目和目标文件-->finish
13.将jar包传到namenode,并保证集群是正确启动
14.将输入文件传到hdfs
hadoop fs -put 1.txt /user/w4xj/wordcount_input
14.执行wordcount程序:因为这里项目打成jar包,所以必须要跟Driver全类名
hadoop jar wc.jar com.w4xj.mapreduce.test.wordcount.WordCountDriver /user/w4xj/wordcount_input /user/w4xj/wordcount_output
15.运行结果
16.查看运行结果
hadoop fs -cat /user/w4xj/wordcount_output/p*