WordCountMapper:
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;
/**
* mapper类继承Mapper 表示我们的这个class类是一个标准的mapper类,需要四个泛型
* k1 v1 k2 v2
*/
public class WordCountMapper extends Mapper<LongWritable,Text,Text,IntWritable>{
Text text = new Text();
IntWritable intWritable = new IntWritable();
/**
* 覆写父类的map方法,每一行数据要调用一次map方法,我们的处理逻辑都写在这个map方法里面
* @param key
* @param value
* @param context
* @throws IOException
* @throws InterruptedException
*
*
* hdfs的最原始数据
hello,world,hadoop
hive,sqoop,flume,hello
kitty,tom,jerry,world
hadoop
经过第一步:TextInputFormat之后
0 hello,world,hadoop
18 hive,sqoop,flume,hello
40 kitty,tom,jerry,world
61 hadoop
*
*
*/
/**
*
* @param key 我们的key1 行偏移量 ,一般没啥用,直接可以丢掉
* @param value 我们的value1 行文本内容,需要切割,然后转换成新的k2 v2 输出
* @param context 上下文对象,承接上文,把数据传输给下文
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
/*
hello,world,hadoop
hive,sqoop,flume,hello
kitty,tom,jerry,world
hadoop
*/
String line = value.toString();
String[] split = line.split(",");
//遍历我们切割出来的单词
for (String word : split) {
text.set(word);
intWritable.set(1);
//写出我们的k2 v2 这里的类型跟我们的k2 v2 保持一致
context.write(text,intWritable);
}
}
}
WordCountReducer:
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* 我们自定的class类继承reducer类表明我们这是一个标准的reducer类
* 跟我们的k2 v2 k3 v3 四个泛型
*/
public class WordCountReducer extends Reducer<Text,IntWritable,Text,IntWritable>{
/**
* 覆写reduce方法,
* @param key 接收的key 是我们的K2
* @param values 接收到value是一个集合 集合里面的数据类型是 v2 类型
* @param context 上下文对象,将我们的数据往外写
* @throws IOException
* @throws InterruptedException
*
*
*
*/
/*
hello,world,hadoop
hive,sqoop,flume,hello
kitty,tom,jerry,world
hadoop
hello <1,1>
world <1,1>
hadoop <1,1>
*/
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int a = 0;
for (IntWritable value : values) {
int i = value.get();
a += i;
}
//将我们的数据写出去
context.write(key,new IntWritable(a));
}
}
JobMain :
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;
public class JobMain extends Configured implements Tool {
@Override
public int run(String[] args) throws Exception {
//获取一个job对象,用于我们任务的组织,通过job对象将我们八个步骤组织到一起,提交给yarn集群运行
Job job = Job.getInstance(super.getConf(), "xxx");
//如果需要打包运行,一定得要加上这一句
job.setJarByClass(JobMain.class);
//获取到我们的job对象之后,通过job对象来组织我们的八个class类到一起,然后提交给yarn集群运行即可
//第一步:读取文件,解析成key,value对,这里是k1 v1
job.setInputFormatClass(TextInputFormat.class);
//集群运行模式,从hdfs上面读取文件
// TextInputFormat.addInputPath(job,new Path("hdfs://node01:8020/wordcount"));
//使用本地模式来运行,从本地磁盘读取文件进行处理
TextInputFormat.addInputPath(job,new Path("file:///F:\\wordcount\\input"));
//第二步:自定义map逻辑,接收第一步的k1,v1 转换成新的k2 v2 进行输出
job.setMapperClass(WordCountMapper.class);
//设置我们key2的类型
job.setMapOutputKeyClass(Text.class);
//设置我们的v2类型
job.setMapOutputValueClass(IntWritable.class);
/**
* 第三到六步
* 第三步:分区 相同key的value发送到同一个reduce里面去,形成一个集合
* 第四步:排序
* 第五步:规约
* 第六步:分组
* 都省掉
*/
//第七步:设置我们的reduce类,接受我们的key2 v2 输出我们k3 v3
job.setReducerClass(WordCountReducer.class);
//设置我们key3输出的类型
job.setOutputKeyClass(Text.class);
//设置我们value3的输出类型
job.setOutputValueClass(IntWritable.class);
//第八步:设置我们的输出类 outputformat
job.setOutputFormatClass(TextOutputFormat.class);
//输出路径输出到hdfs上面去,表示我打包到集群上面去运行
// TextOutputFormat.setOutputPath(job,new Path("hdfs://node01:8020/wordcountout"));
//使用本地模式来运行
TextOutputFormat.setOutputPath(job,new Path("file:///F:\\wordcount\\output2"));
//提交我们的任务
boolean b = job.waitForCompletion(true);
return b?0:1;
}
public static void main(String[] args) throws Exception {
Configuration configuration = new Configuration();
//提交我们的job任务
//任务完成之后,返回一个状态码值,如果状态码值是0,表示程序运行成功
int run = ToolRunner.run(configuration, new JobMain(), args);
System.exit(run);
}
}
wordcount.txt内容
hello,hello
world,world
hadoop,hadoop
hello,world
hello,flume
hadoop,hive
hive,kafka
flume,storm
hive,oozie
output的结果:
flume 2
hadoop 3
hello 4
hive 3
kafka 1
oozie 1
storm 1
world 3