MapReduce是由Google提出的一种分布式计算模型,主要用于搜索领域,解决海量数据的计算问题。它实现了把简单的运算逻辑扩展到海量数据的场景中,进行分布式运行,对于普通程序员来说只需要编写业务逻辑来实现海量数据的处理,而不需要过多的去关注分布式实现细节.
Mapreduce分为map阶段与reduce阶段,开发者只需要实现map()和reduce()两个函数,即可实现分布式计算。
一、 mapreduce的执行步骤
1. 作业配置2.提交作业3.作业初始化4.任务分配5.任务执行6.进度与状态更新7.作业完成
map任务处理(局部处理)
读取输入文件内容,解析成key、value对。对输入文件的每一行,解析成key、value对。每一个键值对调用一次ma
p函数。
编写业务逻辑,对输入的key、value处理,转换成新的key、value输出。
reduce任务处理(汇总)
在reduce之前,有一个shuffle的过程对多个map任务的输出进行合并、排序。
编写业务逻辑,对map输入的key、value处理,转换成新的key、value输出。
把reduce的输出保存到文件中。
Hadoop 2.0引入YARN,大大提高了集群的资源利用率并降低了集群管理成本。
yarn处理的逻辑图
ResourceManager是yarn框架里的主节点,编写好mr程序后,调用hadoop jar xxx.jarxxx.xxxxx.xxxxxxRunner
1.当执行Runner中的job.waitforcompletion()就会启动一个Runjar,Runnjar负责与集群通信
2.Runjar启动后,就会向ResourceManager申请执行一个job,ResourceManager应答,返回job相关资源(staging-dir)和本次job的id
3.Runjar得到应答后,就会提交资源到HDFS下的/tmp/…
4.Runjar向ResourceManager汇报提交结果
5.ResourceManager将本次的job相关信息(比如,分配到哪些NodeManager上运行)加入任务队列
6.NodeManager会通过心跳通信机制去检查任务队列
7.当发现有自己的任务的时候,就向ResourceManager领取任务,领取到任务后,就会分配一个容器Container,容器中包含运行本次job任务的相关资源(CPU,IO,内存…),还会将与job相关的配置与jar包,取到Container中。
8.而具体的mr运行,yarn是无法管理的,mr的运行是由mapreduce框架来管理的,yarn通过启动MRAppMaster(动态产生)来管理整个mr程序。
9.MRAppMaster启动后向ResourceManager注册,然后请求被分配的资源的信息(nodemanager的分配情况)。MRAppMaster获取到信息后,找到相应的节点,在Container中启动mr任务。(在相应节点上可以查看到进程名yarnChild)
10.job完成后向ResourceManager注销,ResourceManager回收资源。
Yarn并不负责管理mr程序,只是负责资源的调度,使的yarn的通用性得到增强,不仅仅是mr程序,其他程序比如strom,但是必须实现yarn的APPMaster接口,有yarn来启动xxAppMaster,xxAppMaster来管理相应的程序。
二、MapReduce实例代码
public class WordCountMapper extends
Mapper<LongWritable, Text, Text, LongWritable> {
protected void map(LongWritable key, Text value, Context context)
throws java.io.IOException, InterruptedException {
String line = value.toString();
String[] fields = line.split("\t");
for (String k : fields) {
context.write(new Text(k), new LongWritable(1));
}
};
}
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class WordCountReducer extends
Reducer<Text, LongWritable, Text, LongWritable> {
protected void reduce(Text key, Iterable<LongWritable> values,
Context context) throws java.io.IOException, InterruptedException {
long count = 0;
for (LongWritable v : values) {
count += v.get();
}
context.write(key,new LongWritable(count));
};
}
package cn.hadoop.mr.wc;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WordCountRunner {
public static void main(String[] args)throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
job.setJarByClass(WordCountRunner.class);
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
FileInputFormat.setInputPaths(job, new Path("hdfs://Wang-HP:9000/wc/src"));
FileOutputFormat.setOutputPath(job, new Path("hdfs://Wang-HP:9000/wc/output2"));
job.waitForCompletion(true);
}
}