我是靠谱客的博主 粗心钻石,最近开发中收集的这篇文章主要介绍大数据之Yarn1. Yarn 基本架构2. Yarn 工作机制3. 作业提交全过程4. 资源调度器5. 容量调度器多队列提交案例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

大数据之Yarn

  • 1. Yarn 基本架构
  • 2. Yarn 工作机制
  • 3. 作业提交全过程
    • 总结
  • 4. 资源调度器
    • 4.1 先进先出调度器(FIFO)
    • 4.2 容量调度器(Capacity Scheduler)
    • 4.3 公平调度器(Fair Scheduler)
  • 5. 容量调度器多队列提交案例
    • 1. 需求
    • 2. 如何配置
    • 3.实操一下

Yarn就是管理整个集群资源的操作平台,你可以看作是资源池,而MapReduce是需要Yarn的资源支持的运算程序。介绍完,我会把整个的Yarn、HDFS、MapReduce等串联起来,看他们是如何依赖彼此的。

1. Yarn 基本架构

之前在Hadoop入门的时候介绍过Yarn的整体架构,今天就在介绍一遍,带大家回顾一下。
YARN主要是由ResourceManager、NodeManager、ApplicationMaster和Container还有客户端等组成。我们在来看一下下图:

在这里插入图片描述

2. Yarn 工作机制

上一章中很清晰的表达了各个组件的职责,我就来讲一下我在开发过程中认为会出现坑的地方。
我经常会在一个job的工作流程时会出现混淆,比如job提交后,每个节点的资源分配以及结束具体的流程,接下来我会来仔细介绍。
首先我们先来看下图:

在这里插入图片描述

上图中,我们按照序号分别来介绍一下整体的流程。
(1)job提交任务,申请一个application
(2)ResourceManager接收到提交申请后,会将资源路径返回给客户端。
(3)客户端提交运行所需资源到hdfs://staging//application,资源包括job.split、job.xml、以及jar包。
(4)客户端资源提交完毕,向ResouceManager申请运行mrAppMaster。
(5)RecouceManager将用户的请求初始化一个Task.
(6)这个任务是启动mrApplication,它会进入到队列进入等待,当队列前面的任务完成后,排到这个任务后,会分配一个节点NodeManager来运行任务。
(7)NodeManager内会创建一个Container容器。
(8)Container会下载之前客户端提交的资源。
(9)当MRAppmaster下载完资源后,会再向ResourceManager提交任务来运行job。
(10)接下来轮到ResouceManager来再次分配资源来运行MapTask,分配两个节点来运行。
(11)两个节点分别领取到任务后,会创建容器。
(12)MRApplication会发送程序启动的脚本给两个节点,节点上会运行输出两个分区排序好的文件。
(13)MRApplication会再向ResourceManager申请ReduceTask的资源,分配了两个节点,来运行程序。
(14)两个NodeManager会创建container,并且向map来获取排序分区好的数据,然后输出。
(15)程序运行完毕后,MR会向RM申请注销自己。

3. 作业提交全过程

作业提交的全过程和Yarn的工作机制是一样的,我们来看一下下图:

在这里插入图片描述

总结

我在这里来串一下,HDFS、Yarn以及MapReduce是如何交互的,来看一下下图,我们可以看出来,我们HDFS上存储的数据被MapReduce阶段读取后经过处理后存储存储到HDFS上,其中和Yarn交互,借用资源来运行MapReduce,这就是三者的交互。

在这里插入图片描述

4. 资源调度器

目前,Hadoop作业调度器主要有三种:FIFO、Capacity Scheduler和Fair Scheduler。Hadoop3默认的是Capacity Scheduler。下面来看一下三个调度器!

4.1 先进先出调度器(FIFO)

在这里插入图片描述

Hadoop最初设计目的是支持大数据批处理作业,如日志挖掘、Web索引等作业,
为此,Hadoop仅提供了一个非常简单的调度机制:FIFO,即先来先服务,在该调度机制下,所有作业被统一提交到一个队列中,Hadoop按照提交顺序依次运行这些作业。
但随着Hadoop的普及,单个Hadoop集群的用户量越来越大,不同用户提交的应用程序往往具有不同的服务质量要求,典型的应用有以下几种:
批处理作业:这种作业往往耗时较长,对时间完成一般没有严格要求,如数据挖掘、机器学习等方面的应用程序。
交互式作业:这种作业期望能及时返回结果,如SQL查询(Hive)等。
生产性作业:这种作业要求有一定量的资源保证,如统计值计算、垃圾数据分析等。
此外,这些应用程序对硬件资源需求量也是不同的,如过滤、统计类作业一般为CPU密集型作业,而数据挖掘、机器学习作业一般为I/O密集型作业。因此,简单的FIFO调度策略不仅不能满足多样化需求,也不能充分利用硬件资源。

4.2 容量调度器(Capacity Scheduler)

在这里插入图片描述

Capacity Scheduler Capacity Scheduler 是Yahoo开发的多用户调度器,它以队列为单位划分资源,每个队列可设定一定比例的资源最低保证和使用上限,同时,每个用户也可设定一定的资源使用上限以防止资源滥用。而当一个队列的资源有剩余时,可暂时将剩余资源共享给其他队列。
总之,Capacity Scheduler 主要有以下几个特点:
①容量保证。管理员可为每个队列设置资源最低保证和资源使用上限,而所有提交到该队列的应用程序共享这些资源。
②灵活性,如果一个队列中的资源有剩余,可以暂时共享给那些需要资源的队列,而一旦该队列有新的应用程序提交,则其他队列借调的资源会归还给该队列。这种资源灵活分配的方式可明显提高资源利用率。
③多重租赁。支持多用户共享集群和多应用程序同时运行。为防止单个应用程序、用户或者队列独占集群中的资源,管理员可为之增加多重约束(比如单个应用程序同时运行的任务数等)。
④安全保证。每个队列有严格的ACL列表规定它的访问用户,每个用户可指定哪些用户允许查看自己应用程序的运行状态或者控制应用程序(比如杀死应用程序)。此外,管理员可指定队列管理员和集群系统管理员。
⑤动态更新配置文件。管理员可根据需要动态修改各种配置参数,以实现在线集群管理。

4.3 公平调度器(Fair Scheduler)

在这里插入图片描述
在这里插入图片描述

Fair Scheduler Fair Schedulere是Facebook开发的多用户调度器。
公平调度器的目的是让所有的作业随着时间的推移,都能平均地获取等同的共享资源。当有作业提交上来,系统会将空闲的资源分配给新的作业,每个任务大致上会获取平等数量的资源。和传统的调度策略不同的是它会让小的任务在合理的时间完成,同时不会让需要长时间运行的耗费大量资源的任务挨饿!
同Capacity Scheduler类似,它以队列为单位划分资源,每个队列可设定一定比例的资源最低保证和使用上限,同时,每个用户也可设定一定的资源使用上限以防止资源滥用;当一个队列的资源有剩余时,可暂时将剩余资源共享给其他队列。
当然,Fair Scheduler也存在很多与Capacity Scheduler不同之处,这主要体现在以下几个方面:
①资源公平共享。在每个队列中,Fair Scheduler 可选择按照FIFO、Fair或DRF策略为应用程序分配资源。其中,
FIFO策略
公平调度器每个队列资源分配策略如果选择FIFO的话,就是禁用掉每个队列中的Task共享队列资源,此时公平调度器相当于上面讲过的容量调度器。
Fair策略
Fair 策略(默认)是一种基于最大最小公平算法实现的资源多路复用方式,默认情况下,每个队列内部采用该方式分配资源。这意味着,如果一个队列中有两个应用程序同时运行,则每个应用程序可得到1/2的资源;如果三个应用程序同时运行,则每个应用程序可得到1/3的资源。
DRF策略
DRF(Dominant Resource Fairness),我们之前说的资源,都是单一标准,例如只考虑内存(也是yarn默认的情况)。但是很多时候我们资源有很多种,例如内存,CPU,网络带宽等,这样我们很难衡量两个应用应该分配的资源比例。
那么在YARN中,我们用DRF来决定如何调度:假设集群一共有100 CPU和10T 内存,而应用A需要(2 CPU, 300GB),应用B需要(6 CPU, 100GB)。则两个应用分别需要A(2%CPU, 3%内存)和B(6%CPU, 1%内存)的资源,这就意味着A是内存主导的, B是CPU主导的,针对这种情况,我们可以选择DRF策略对不同应用进行不同资源(CPU和内存)的一个不同比例的限制。
②支持资源抢占。当某个队列中有剩余资源时,调度器会将这些资源共享给其他队列,而当该队列中有新的应用程序提交时,调度器要为它回收资源。为了尽可能降低不必要的计算浪费,调度器采用了先等待再强制回收的策略,即如果等待一段时间后尚有未归还的资源,则会进行资源抢占:从那些超额使用资源的队列中杀死一部分任务,进而释放资源。
yarn.scheduler.fair.preemption=true 通过该配置开启资源抢占。
③提高小应用程序响应时间。由于采用了最大最小公平算法,小作业可以快速获取资源并运行完成

5. 容量调度器多队列提交案例

1. 需求

Yarn默认的容量调度器是一条单队列的调度器,在实际使用中会出现单个任务阻塞整个队列的情况。同时,随着业务的增长,公司需要分业务限制集群使用率。这就需要我们按照业务种类配置多条任务队列。

2. 如何配置

默认Yarn的配置下,容量调度器只有一条Default队列。在capacity-scheduler.xml中可以配置多条队列,并降低default队列资源占比:

<!-- 指定多队列,增加hive队列 -->
<property>  
   <name>yarn.scheduler.capacity.root.queues</name>
   <value>default,hive</value>
   <description>
     The queues at the this level (root is the root queue).
   </description>
</property>

<!-- 降低default队列资源额定容量为40%,默认100% -->
<property>
   <name>yarn.scheduler.capacity.root.default.capacity</name>
   <value>40</value>
</property>

<!-- 降低default队列资源最大容量为60%,默认100% -->
<property>
   <name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
   <value>60</value>
</property>

同时为新加队列添加必要属性:

<!-- 指定hive队列的资源额定容量 -->
<property>
   <name>yarn.scheduler.capacity.root.hive.capacity</name>
   <value>60</value>
</property>

<property>
   <name>yarn.scheduler.capacity.root.hive.user-limit-factor</name>
   <value>1</value>
</property>

<!-- 指定hive队列的资源最大容量 -->
<property>
   <name>yarn.scheduler.capacity.root.hive.maximum-capacity</name>
   <value>80</value>
</property>

<property>
   <name>yarn.scheduler.capacity.root.hive.state</name>
   <value>RUNNING</value>
</property>

<property>
   <name>yarn.scheduler.capacity.root.hive.acl_submit_applications</name>
   <value>*</value>
</property>

<property>
   <name>yarn.scheduler.capacity.root.hive.acl_administer_queue</name>
   <value>*</value>
</property>

<property>
   <name>yarn.scheduler.capacity.root.hive.acl_application_max_priority</name>
   <value>*</value>
</property>

<property>
   <name>yarn.scheduler.capacity.root.hive.maximum-application-lifetime</name>
   <value>-1</value>
</property>

<property>
   <name>yarn.scheduler.capacity.root.hive.default-application-lifetime</name>
   <value>-1</value>
</property>

哦吼,配置完成后,记得重新启动一下yarn,来刷新一下队列。

3.实操一下

我们还是以wc的案例来操作一下:

public class WcMapper  extends >Mapper<LongWritable, Text,Text, IntWritable> {
   private Text k = new Text();
   private IntWritable v = new IntWritable(1);
   @Override
   protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
       //以空格分割字符
       String[] words = value.toString().split(" ");
       //输出
       for (String word : words) {
           k.set(word);
           context.write(k,v);
       }
   }
}
public class WcReducer extends >Reducer<Text, IntWritable,Text,IntWritable> {
   private int sum;
   private IntWritable v = new IntWritable();
   @Override
   protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
      //累加求和
       sum = 0;
       for (IntWritable value : values) {
           sum += value.get();
       }
       //输出
       v.set(sum);
       context.write(key,v);
   }
}
public class WcDriver{
   public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
       //获取job对象
       Configuration configuration = new Configuration();
       //设置HDFS NameNode的地址
       configuration.set("fs.defaultFS", "hdfs://hadoop102:9820");
       // 指定MapReduce运行在Yarn上
       configuration.set("mapreduce.framework.name","yarn");
       // 指定mapreduce可以在远程集群运行
       configuration.set("mapreduce.app-submission.cross-platform","true");
       //指定Yarn resourcemanager的位置
       configuration.set("yarn.resourcemanager.hostname","hadoop103");
       //将任务提交到hive队列
       configuration.set("mapreduce.job.queuename","hive");
       Job job = Job.getInstance(configuration);
       //设置driver的jar包
      //job.setJarByClass(WcDriver.class);
      job.setJar("D:\code\mapreduce\target\mapreduce-1.0-SNAPSHOT.jar");
       //设置mapper和reducer的jar包
       job.setMapperClass(WcMapper.class);
       job.setReducerClass(WcReducer.class);
       //设置mapper的输出类型
       job.setMapOutputKeyClass(Text.class);
       job.setMapOutputValueClass(IntWritable.class);
       //设置最终输出kv类型
       job.setOutputKeyClass(Text.class);
       job.setOutputValueClass(IntWritable.class);
       //设置输入路径和输出路径
       FileInputFormat.setInputPaths(job,new Path(args[0]));
       FileOutputFormat.setOutputPath(job,new Path(args[1]));
       //提交job
       boolean result = job.waitForCompletion(true);
       System.exit(result? 0 : 1);

   }
}

我们来看一下运行页面,是否换了我们修改的hive队列??!

在这里插入图片描述

看来是成功了!到这里,基本上Hadoop的三个大框架已经差不多结束了,后面我还会分享一些开发过程中处理一些问题的优化。

最后

以上就是粗心钻石为你收集整理的大数据之Yarn1. Yarn 基本架构2. Yarn 工作机制3. 作业提交全过程4. 资源调度器5. 容量调度器多队列提交案例的全部内容,希望文章能够帮你解决大数据之Yarn1. Yarn 基本架构2. Yarn 工作机制3. 作业提交全过程4. 资源调度器5. 容量调度器多队列提交案例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部