MapReduce编程规范及示例编写
编程规范
MapReduce的开发一共有八个步骤。其中,
map阶段分为2个步骤,
shuffle阶段4个步骤,
reduce阶段分为2个步骤。
Map阶段2个步骤
第一步:设置inputFormat类,将我们的数据切分成key-value对(k1,v1),输入到第二步。
第二步:自定义map逻辑,处理我们第一步的输入数据,然后转换成新的key,value对(k2,v2)进行输出。
shuffle阶段4个步骤
第三步:对输出的key,value对(k2,v2)进行分区
第四步:对不同分区的数据按照相同的key进行排序
第五步:对分组后的数据进行规约(combine操作),降低数据的网络拷贝(可选步骤)
第六步:对排序后的数据进行分组,分组的过程中,将相同key的value放到一个集合当中
(分区,排序,规约,分组)
reduce阶段2个步骤
第七步:对多个map的任务进行合并排序,编写reduce函数自己的逻辑,对输入的key,value对(k2,v2)进行处理,转换成新的key,value对(k3,v3)进行输出
第八步:设置outputformat将输出的key,value对数据进行保存到文件中
WordCount示例编写
需求:在一堆给定的文本文件中统计输出每一个单词出现的总次数.
数据准备:
vim wordcount.txt
hello,hello,hadoop
hive,sqoop,flume,hello
kitty,tom,jerry,world
hdfs dfs -mkdir /wordcount/input
hdfs dfs -put wordcount.txt /wordcount/input
定义一个mapper类
package com.fgm.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;
/**
*
* @Auther: fgm
*/
public class WordCountMapper extends Mapper<LongWritable,Text,Text,IntWritable> {
/**
*
* @param key k1
* @param value v1
* @param context 上下文对象
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] split = value.toString().split(",");
for (String word : split) {
//获取单词,写出,每获取一次,value均增加1
context.write(new Text(word),new IntWritable(1));
}
}
}
定义一个reducer类
package com.fgm.wordcount;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* @Auther: fgm
* 继承reducer类,来实现我们的数据的进一步的处理,需要四个泛型
* 输入的是k2,v2
* 输出的k3,v3
*/
public class WordCountReducer extends Reducer<Text,IntWritable,Text,IntWritable> {
/**
* 撰写我们自己的reduce 方法
* @param key
* @param values
* @param context
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum =0;
for (IntWritable value : values) {
int i=value.get();
sum+=i;
}
context.write(key,new IntWritable(sum));
}
}
定义一个主类,提交job
package com.fgm.wordcount;
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;
/**
*通过mr的编程模板设置主类
* @Auther: fgm
*/
public class WordCountMain extends Configured implements Tool {
@Override
public int run(String[] args) throws Exception {
Job job = Job.getInstance(super.getConf(), "xxxx");
job.setJarByClass(WordCountMain.class);
//第一步 读取文件,解析成key,value 对
job.setInputFormatClass(TextInputFormat.class);
//设置我们读取的路径
TextInputFormat.addInputPath(job,new Path("hdfs://node01:8020/wordcount/input"));
//第二步 自定义map逻辑,接收我们的k1 v1 ,转换成k2 v2输出
job.setMapperClass(WordCountMapper.class);
//设置k2 v2的类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
//第三步 到第六步 分区 排序 规约 分组(可以省略,按照默认)
//第七步 自定义reduce逻辑,接收我们的k2,v2输出成k3,v3
job.setReducerClass(WordCountReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
//第8步,设置我们输出的目的地
job.setOutputFormatClass(TextOutputFormat.class);
TextOutputFormat.setOutputPath(job, new Path("hdfs://node01:8020/wordcount/output"));
//设置我们的job任务等待退出
boolean b = job.waitForCompletion(true);
return b?0:1;
}
public static void main(String[] args) throws Exception {
//程序执行的最终结果
int run = ToolRunner.run(new Configuration(), new WordCountMain(), args);
//判断执行结果
System.exit(run);
}
}
注意:hdfs://node01:8020/wordcount/output目录在程序运行前应不存在。
MapReduce程序运行模式
本地运行模式
(1)mapreduce程序是被提交给LocalJobRunner在本地以单进程的形式运行
(2)而处理的数据及输出结果可以在本地文件系统,也可以在hdfs上
(3)怎样实现本地运行?写一个程序,不要带集群的配置文件
本质是程序的conf中是否有mapreduce.framework.name=local以及yarn.resourcemanager.hostname=local参数
(4)本地模式非常便于进行业务逻辑的debug。
集群运行模式
(1)将mapreduce程序提交给yarn集群,分发到很多的节点上并发执行
(2)处理的数据和输出结果应该位于hdfs文件系统
(3)提交集群的实现步骤:
将程序打成JAR包,然后在集群的任意一个节点上用hadoop命令启动
yarn jar hadoop_hdfs_operate-1.0-SNAPSHOT.jar com.fgm.hdfs.wordcount.WordCountMain