shell端执行mapreduce
1.准备数据,这个数据必须存储在hdfs上,并不是linux目录上的数据
2.mapreduce程序
Wordcount---->词频统计
/export/servers/hadoop-2.6.0-cdh5.14.0/share/hadoop/mapreduce/mr-examples(有很多的jar包)
3.将mapreduce程序提交到yarn上面去运行
提交方式只有一种:
后面跟jar的文件 以及运行的主类
Bin/yarn jar share/hadoop/mapreduce/mr-examples
In:表示mapreduce程序要数据所在的位置
Out:mapredecde 程序输出所在位置 该目录必须不存在
Mapreduce 数据处理过程
1.Input (确保数据保存在HDFS上,当然你可以选择本地运行)
2.map(数据先缓存在内存中,溢出到磁盘中)
3.shuffle(框架自动执行)
4.reduce(对shuffle的结果进行合并)
5.output(存放结果的目录必须事先不存在)
input 和 output 不需要我们去编写过多的代码,主要是给个路径就可以
着重关注map 和 reduce,两者都只是一个方法,我们只需要去重写方法。
源码:
在编写代码之前,把集群的配置文件导入idea
package mapredeuce;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
public class wordcount {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
// System.setProperty("hadoop.home.dir", "E:\\hadoop-2.6.5\\");
//System.out.println(args[0]);参数从这里获取
//1.读取配置文件(知道hdfs在哪里了)
Configuration conf = new Configuration();
//2.创建job
Job job = Job.getInstance(conf,"wordcount");
//设置Job运行的主类
job.setJarByClass(wordcount.class);
//3.设置job 从哪里读数据 怎么处理 怎么输出
//input
Path inputPath = new Path(args[0]);
FileInputFormat.setInputPaths(job,inputPath);//读取文件规则 格式化
//map
job.setMapperClass(wordcountMapper.class);//map用哪个类处理 null
job.setMapOutputKeyClass(Text.class);//先是null
job.setMapOutputValueClass(IntWritable.class); //null
//补充
//shuffle
//reduce
job.setReducerClass(wordcountReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
//output
Path outputPath = new Path(args[1]);
FileOutputFormat.setOutputPath(job,outputPath);
//任务提交
boolean isSuccess = job.waitForCompletion(true);
//成功 0 否则就是1
System.exit(isSuccess?0:1);
}
/**
*
*
* class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
*
* keyin :输入 long 行偏移量
*
* valuein:行内容 text
*
* keyout: text
*
* valueout:intWritable
*/
private static class wordcountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
private Text mapOutputKey = new Text();
private final static IntWritable mapOutputValue=new IntWritable(1);
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//将行内容转换成字符串类型
String valueStr = value.toString();
//使用空格分隔单词
String [] items = valueStr.split(" ");
//一个单词一个单词的输出
for (String str : items){
mapOutputKey.set(str);//str---》text
//通过此对象,将Map的结果进行输出 格式化
context.write(mapOutputKey,mapOutputValue);
}
}
}
/**\
*
*
* class Reducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
*
* keyin : text
* valuein :intWritable
* keyout:text
* valueout: intWritable
*/
private static class wordcountReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
private IntWritable Sum = new IntWritable();//承接没包装的sum
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
//主要对每个key携带的values进行累加
int sum =0;
for (IntWritable value : values){
sum += value.get();//intWritable--->int
}
Sum.set(sum);
context.write(key,Sum);
}
}
}