MapReduce
- 经过map阶段进行shuflle(洗牌),将获得的每个kv(key,value) 分发给reduce阶段,如果存在相同的key会给同一个ruduce task 任务去进行reduce.将相同的key 聚合在一个reduce task 任务中.
shuffle必定会将相同的KV 分发给相同的reduce task
wordCount案例的map阶段
/**
* KEYIN:输入数据KV中的key的数据类型
* VALUEIN:输入数据KV中的value的数据类型
* KEYOUT:输出数据KV中的key的数据类型
* VALUEOUT:输出数据KV中的value的数据类型
*
*/
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
/**
* map 方法是提供给map task 进程来调用的,map task进程是每读取一行文本来调用一次我们自定义的map的方法 map task
* 在调用map方法时 ,传递的参数 一行的起始偏移量为LongWritable类型的key , 一行的文本内容为Text类型的value
*/
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
// 将一行文本的内容转换为String类型
String line = value.toString();
// 将这一行的数据切分成单词
String[] words = line.split(" ");
// 输出单词
for (String word : words) {
context.write(new Text(word), new IntWritable(1));
}
}
}
- wordCount案例的reduce阶段
/**
* KEYIN:对应mapper阶段输出的key的类型
* VALUEIN:对应mapper阶段输出的value的类型
* KEYOUT:对应reduce阶段输出的key的类型
* VALUEOUT:对应reduce阶段输出的value的类型
*
*/
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
/**
* reduce 方法时提供给reduce task进程来调用
*
* reduce 将shuffle 阶段分发过来的大量的key数据进行聚合,聚合的机=机制是相同的KV对聚合为一组,然后,reduce task 对每一组聚合KV调用一次自定义的reduce方法
*
*/
@Override
protected void reduce(Text key, Iterable<IntWritable> vlaues,
Context context) throws IOException, InterruptedException {
// 定义一个计数器
int count = 0;
// 通过values这个迭代器,遍历这一组KV中所有的value,进行累加
for (IntWritable value : vlaues) {
count += value.get();
}
//输出单词的统计结果
context.write(key, new IntWritable(count));
}
}
- Job阶段
/**
* 客户端提交job
*
*/
public class WordCountJobSubmiter {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
// 获取实例对象
Job wordCountJob = Job.getInstance(conf);
// 重要:如果要运行在hadoop上 需要指定job所在的jar包
wordCountJob.setJarByClass(WordCountJobSubmiter.class);
// 设置wordCountJob所用的mapper逻辑类为那个类
wordCountJob.setMapperClass(WordCountMapper.class);
// 设置wordCountJob所用的reducer逻辑类为那个类
wordCountJob.setReducerClass(WordCountReducer.class);
// 设置map阶段输出的KV数据类型
wordCountJob.setMapOutputKeyClass(Text.class);
wordCountJob.setMapOutputValueClass(IntWritable.class);
// 设置reduce最终输出的KV数据类型
wordCountJob.setOutputKeyClass(Text.class);
wordCountJob.setOutputValueClass(IntWritable.class);
// 设置要处理的文本数据存放的路径
FileInputFormat.setInputPaths(wordCountJob, "hdfs://hadoop1:9000/wordCount/srcdata/");
// 设置最终处理结果存放的路径
FileOutputFormat.setOutputPath(wordCountJob, new Path("hdfs://hadoop1:9000/wordCount/output/"));
// 提交Job给hadoop集群去执行
wordCountJob.waitForCompletion(true);
}
}
在hadoop上运行jar包 尽量使用hadoop jar去执行jar包
hashpartitioner shuffle分区