文章目录
- MapReduce简介
- MR核心编程思想
- MapReduce的优缺点
- 优点:
- 缺点:
- MapReduce编程
- 自动化调度平台yarn
- yarn两大服务进程——Resource Manager和Node Manager
- yarn中的调度
- 调度选项
- yarn集群搭建
MapReduce简介
Hadoop通过分布式文件系统Hdfs来实现对海量数据的存储,除此之外,Hadoop还提供了分布式计算框架MapReduce来用于海量数据的计算。
MapReduce是Hadoop的分布式运算组件,是Hadoop数据分析应用的核发框架,将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发的运行在hadoop集群上。
MapReduce过程主要分为两部分,Map和Reduce。Map阶段把数据拆分处理输出,Reduce把Map阶段输出的数据整合处理。
MR核心编程思想
上面的流程可以通过上一篇的手写MR框架来实现。
手写MR框架代码:
MapReduce的优缺点
优点:
- 易于编程
- 良好的拓展性
- 高容错性
- 适合处理PB级别以上的离线处理
缺点:
- 不擅于实时计算
- 不擅长做流式计算(非静态资源)
- 不支持DAG(有向图)计算(可用spark)
MapReduce编程
编写MR程序分成三阶段:Mapper阶段,Reduce阶段,Driver阶段。下面以WorkCount例子为例。
MapReduce相关包:
<!--导入MapReduce包 start-->
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-mapreduce-client-app -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-app</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-hs</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-hs-plugins</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-jobclient</artifactId>
<version>2.8.4</version>
</dependency>
<!--导入MapReduce包 end-->
Mapper阶段:
(1)用户自定义mapper类 要继承父类Mapper
(2)Mapper的输入数据的kv对形式(kv类型可以自定义)
(3)Mapper的map方法的重写(加入业务逻辑)
(4)Mapper的数据输出kv对的形式(kv类型可以自定义)
(5)map()方法(maptask进程)对每个<k,v>调用一次
package com.even.mr.example1;
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;
/**
* des:
* author: Even
* create date:2018/12/16
*/
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
/*1,获取数据*/
String line = value.toString();
/*2,切分数据*/
String[] words = line.split("\t");
/*3,传输数据*/
for (String word : words) {
context.write(new Text(word), new IntWritable(1));
}
}
}
Reduce阶段:
(1)用户自定义reducer类 要继承父类Reducer
(2)Reducer的数据输入类型对应的是Mapper阶段的输出数据类型,也是kv对
(3)Reducer的reduce方法的重写(加入业务逻辑)
(4)ReduceTask进程对每组的k的<k,v>组调用一次reduce方法
package com.even.mr.example1;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.mapreduce.Reducer;
import javax.xml.soap.Text;
import java.io.IOException;
/**
* des:
* author: Even
* create date:2018/12/16
*/
public class WordCountReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
/*1,定义总数*/
int sum = 0;
/*2,累加求和*/
for (IntWritable value : values) {
sum += value.get();
}
/*3,输出结果*/
context.write(key, new IntWritable(sum));
}
}
Driver驱动类:
mr程序需要一个Driver来进行任务的提交,提交的任务是一个描述了各种重要信息的job对象
package com.even.mr.example1;
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;
import java.io.IOException;
/**
* des:
* author: Even
* create date:2018/12/16
*/
public class WordCountDriver {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration configuration = new Configuration();
Job job = Job.getInstance(configuration);
/*1,定义驱动入口类*/
job.setJarByClass(WordCountDriver.class);
/*2,定义Mapper和Reduce*/
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReduce.class);
/*3,定义Mapper输出键类型和值类型*/
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
/*4,定义Reduce输出键类型和值类型*/
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
/*5,定义输入输出*/
FileInputFormat.setInputPaths(job, new Path("/in"));
FileOutputFormat.setOutputPath(job, new Path("/out"));
System.out.println(job.waitForCompletion(true) ? 1 : 0);
}
}
in文件
even elina lala even alibaba lalo lala mr wordcount
自动化调度平台yarn
上面的程序只是运行在单机模式下,实际大数据运用中,MR程序是运行在集群中,而且需要先执行maptask,等待每个maptask都处理完成后,还需要启动多个reducetask,这个过程需要用到自动化调度平台来帮助我们实现。
hadoop 2.x中提供了分布式调度平台——yarn。yarn帮助我们调度大量的mapreduce程序,并且合理分配运算资源。
yarn两大服务进程——Resource Manager和Node Manager
管理集群上资源使用的资源管理器(resource manager),运行在集群中所有节点上且能够启动和监控窗口(container)的节点管理员(node manager)。其中容器是用于执行特定应用程序的进程,每个容器都有资源限制(内存,cpu等)。根据YARN的配置,一个容器可以是一个unix进程,也可以是一个linux进程。
yarn运行流程:
- 客户端连接资源管理器,要求运行一个application master进程,即第1步;
- 资源管理器开启一个容器,在容器中启动application master,即第2,3步;
- application master运行之后,会做一些计算并把结果返回给客户端,或者向资源管理器请求更多的容器来运算,取决于应用本身。即第4步。
- 请求更多的容器后,需要开启容器,启动application master。5,6步。
ResourceManager作用:
1)处理客户端的请求
2)监控NodeManager
3)启动或者监控程序的运行
4)资源的分配和调度
NodeManager的作用:
1)管理单个节点的资源
2)处理来自RM的命令
3)处理程序的命令
yarn中的调度
Resource manager会处理yarn应用发起的资源请求。而在一个繁忙的集群上,一个应用经常需要等待才能得到所需的资源,yarn调度器的工作就是根据策略为应用分配资源。
调度选项
- FIFO调度器(FIFO Scheduler):将应用放置在一个队列中,然后按照提交顺序运行应用。优点是简单易懂,不需要任何配置,但是不适合共享集群。大的应用会占用集群中的大量资源,且每个应用都必须等待直到轮到自己运行。即小作业一直被阻塞,直到大作业完成。
- 容量调度器(Capacity Scheduler):一个独立的专门队列保证小作业一提交就可以启动,队列容量为小作业所保留,因此是以整个集群利用率为代价的。与FIFO调度相比,大作业执行的时间会更长。
- 公平调度器(Fair Scheduler):不预留一定量的资源,调度器会在所有运行的作业之间动态平衡资源。比如大作业启动时且只有一个作业时,会占用集群中所有的资源,当小作业启动时,大作业会在使用完容器后释放出资源给小作业使用,小作业结束且不再申请资源后,大作业会再次使用所有的资源。
yarn集群搭建
- 修改 hadoop安装目录/etc/hadoop/yarn-site.xml文件
<property>
<name>yarn.resourcemanager.hostname</name>
<!--hadoop集群中resourcemanager的主机-->
<value>hd-even-01</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<!--NodeManager上运行的附属服务,配置mapreduce_shuffle表示运行mapreduce程序-->
<value>mapreduce_shuffle</value>
</property>
- 把修改后的文件复制到集群机器中
//$PWD代表当前目录,意思是把文件拷贝到hd-even-02和hd-even-03主机的当前目录。
scp yarn-site.xml hd-even-02:$PWD
scp yarn-site.xml hd-even-03:$PWD
- 修改 hadoop安装目录/etc/hadoop/slaves文件,列出需要启动nodemanager的机器
hd-even-02
hd-even-03
- 启动yarn集群
启动:
hadoop安装目录/sbin/start-yarn.sh
关闭:
hadoop安装目录/sbin/stop-yarn.sh
- 访问web端口
启动完成后,可以在windows上用浏览器访问resourcemanager的web端口:
http://hd-even-01:8088 - 设置MapReduce使用yarn
#把mapred-site.xml.template重命名为mapred-site.xml添加内容
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
<description>The runtime framework for executing MapReduce jobs.Can be one of local, classic or yarn.
</description>
</property>
- 编译MapReduce程序
#把上面的MapReduce程序打包成jar包,hadoop建立一个/in文件夹,上传一个in文件到hadoop
#pom.xml添加插件
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<!-- 此处指定main方法入口的class -->
<mainClass>com.even.mr.WordCountDriver</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
- 编译命令
#把pom依賴包也一起打包
mvn assembly:assembly
- 运行jar
编译后的jar文件上传到hd-even-01主机。输入命令hadoop jar jar文件
打开:http://hd-even-01:8088/