案例
Map阶段
MapReduce 会自动获得每一行单词的索引.
我们需要的是在 Map 中对每行单词进行单词出现次数的统计.
暂时不需要对相同的KEY进行合并. 除非是一个单词在同一行出现了多次
代码
public class WordCountMapper extends Mapper<LongWritable,Text, Text,LongWritable> {
/**
* 这个方法接收每一行的数据
* 每一行都是 单词首字母在文件中的索引位置
* @param key 单词索引
* @param value 单词
* @param context mapreduce 上下文
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
Text text = new Text();
// value 是每一行单词
// 对 value 进行拆分
String[] line = value.toString().split(",");
for (String word : line) {
// 通过上下文对象传递给下一个步骤
// 可以使 Shuffle阶段,也可以是 Reduce 阶段
text.set(word);
context.write(text,new LongWritable(1));
}
}
}
Shuffle
主要实现 分区 规约 排序 分组
Reduce
对结果进行合并
代码
public class WordCountReduce extends Reducer<Text, LongWritable,Text,LongWritable> {
/**
* @param key 每个单词
* @param values 单词出现次数的集合
* @param context mapreduce 上下文对象
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
Iterator<LongWritable> valueIterator = values.iterator();
Long count = 0L;
while (valueIterator.hasNext()) {
count += valueIterator.next().get();
}
// 将每个单词出现的次数写入到上下文
context.write(key,new LongWritable(count));
}
}
Job
串联起 Map,Shuffle,Reduce 阶段
代码
public class JobMain extends Configured implements Tool {
@Override
public int run(String[] strings) throws Exception {
// 创建一个任务对象
Job job = Job.getInstance(super.getConf(),"mapreduce_word_count");
// 第一步 设置读取文件的类 读取 K1 和 V1 偏移量和单词
job.setInputFormatClass(TextInputFormat.class);
// 设置读取的路径
TextInputFormat.addInputPath(job,new Path(Constant.URL+"/wordcount"));
// 第二步 设置 map 类,
job.setMapperClass(WordCountMapper.class);
// 设置 Mapper 输出K2V2的类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
// 第三步 设置 Shuffle 阶段
// 这一步 采用默认的 分区 排序 规约 分组
// 设置 Reduce 输出的 K3V3 类型
job.setReducerClass(WordCountReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
// 第四步 设置输出类,设置输出文件路径
job.setOutputFormatClass(TextOutputFormat.class);
// 设置输出的路径
TextOutputFormat.setOutputPath(job,new Path(Constant.URL+"/afterwordcount/"));
// 设置任务提交,等待任务完成状态
boolean b = job.waitForCompletion(true);
return b ? 0 : 1;
}
/**
*
* @param args
*/
public static void main(String[] args) throws Exception {
Configuration configuration = new Configuration();
int status = ToolRunner.run(configuration, new JobMain(), args);
System.out.println("任务执行情况"+status);
System.exit(status);
}
}
代码运行在 Hadoop
配置代码
Job job = Job.getINstance(super.getCOnf());
job.seytJarByClass(JobMain.class);
其他操作
将我们的demo 打成 jar.
上传到集群
使用Hadoop 命令运行 jar
hadoop jar jarName.jar com.pinlma.JobMain
hadoop 开头 jar包名称 以及 主类也就是Job类的包名以及类名
总结
Job 的整个流程就是之前文章将的几个步骤
1. 设置读取文件的路径.从哪里读取数据
2. 这是TextInputFormat
3. 设置 Mapper 以及 Mapper 的输出类型
4. 设置Shuffle(这一步暂时略过了)
5. 设置 reduce 以及输出类型
6. 设置 TextOutputFOrmat
7. 设置输出路径
8. 设置等待任务完成.获取状态