什么是Map/Reduce?
MapReduce是hadoop的核心组件之一,主要负责分布式计算
Map/Reduce内部原理:
MapReduce最重要的一个思想:分而治之,就是将负责的大任务分解成若干个小任务, 并行执行, 完成后在合并到一起,适用于大量复杂的任务处理场景,大规模数据处理场景.
Map负责“分”,即把复杂的任务分解为若干个“简单的任务”来并行处理。可以进行拆分的前提是这些小任务可以并行计算,彼此间几乎没有依赖关系。
Reduce负责“合”,即对map阶段的结果进行全局汇总
MR核心思想:“相同”的key为一组,调用一次reduce方法,方法内迭代这一组数据进行计算
统计单词个数:
以一个统计单词个数的例子来说明:
1.有一个源文件,为了便于计算,我们要把它分成多个块
2.每个块里有多个单词,Map把单词作为key,固定一个数值1作为value
3.通过shuffle(洗牌)把相同的单词归为一类,生成类似<hello,{1,1,1}>这样的键值对,然后把输出结果交给Reduce
4.Reduce对结果进行计算,生成每个单词的总数量<hello,3>
Eclipse代码实现:
1.Mapper类
package com.hpe.wc;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
/**
* @author lpq
* @date 2019年6月14日
*
*/
public class MyMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
//相当于Java的int类型,Hadoop的数据类型和Java的数据类型不同
//给每个单词的对应的value值设置为1
private final static IntWritable one = new IntWritable(1);
//key的值----文件里的每个单词
private Text word = new Text();
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//把文件数据按照空格拆分
String[] split = value.toString().split(" ");
//遍历,生成键值对 <单词,1>
for (String str : split) {
//context作用是连接map端和reduce端程序的连接点,输出的数据需要通道context写到磁盘中
context.write(word, one);
System.out.println(word);
}
}
}
2. Reduce类
package com.hpe.wc;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
/**
* @author lpq
* @date 2019年6月14日
*/
public class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
//每个单词的总数量
int sum = 0;
//遍历的是键值对的值,Map的最终输出结果----> <单词,{1,1,1}>
for (IntWritable i : values) {
sum += i.get();
}
context.write(key, new IntWritable(sum));
}
}
3.Job类
package com.hpe.wc;
import org.apache.hadoop.conf.Configuration;
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.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* @author lpq
* @date 2019年6月14日
*/
public class Job1 {
public static void main(String[] args) throws Exception {
System.setProperty("HADOOP_USER_NAME", "root");
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://IP地址:端口号");
Job job = Job.getInstance(conf);
//进程名
job.setJobName("wc2Job");
// 设置运行/处理该作业的类
job.setJarByClass(Job1.class);
job.setMapperClass(MyMapper.class);
job.setReducerClass(MyReducer.class);
//输出的key的类型
job.setMapOutputKeyClass(Text.class);
//输出的value的类型
job.setMapOutputValueClass(IntWritable.class);
//设置需要计算的输入文件路径
//源文件路径
FileInputFormat.setInputPaths(job, new Path("/test/input/aaa.txt"));
//结果的输出路径,必须是不存在的,且必须是文件夹
FileOutputFormat.setOutputPath(job, new Path("/wc"));
//执行结果
boolean zt = job.waitForCompletion(true);
if(zt) {
System.out.println("执行成功");
}
}
}
把项目打成jar包在Linux上运行:hadoop jar jar包路径 类路径 数据源路径 输出路径
Yarn:
在Hadoop2.x版本,Hadoop将自带的资源调度器提取解耦形成一个独立的资源调度器 – Yarn(Yet Another Resource Negotiator),Yarn资源调度器也是主从架构. 主节点是ResourceManager,从节点是NodeManager。其最重要的重构在于将资源分配与任务调度/监控进行了分离.
Yarn资源调度流程图:
Yarn中的几个重要角色:
①ResourceManager(资源调度器):
首先保持和NodeManager的心跳机制, 接受客户端的任务请求, 根据NodeManager报告的资源情况, 启动调度任务, 分配Container给ApplicationMaster, 监控AppMaster的存在情况, 负责作业和资源分配调度, 资源包括CPU, 内存, 磁盘, 网络等, 它不参与具体任务的分配和监控, 也不能管理具体任务的失败和重启等.
②ApplicationMaster(任务管理器):
在其中一台Node机器上, 负责一个Job的整个生命周期. 包括任务的分配调度, 任务的失败和重启管理, 具体任务的所有工作全部由ApplicationMaster全权管理, 就像一个大管家一样, 只向ResourceManager申请资源, 向NodeManager分配任务, 监控任务的运行, 管理任务的失败和重启.
③NodeManager(任务处理器):
负责处理ApplicationMaster分配的任务, 并保持与ResourceManager的心跳机制, 监控资源的使用情况并向RM报告进行报告, 支持RM的资源分配工作.