0%

Hadoop-12-YARN

什么是YARN

Yarn是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操作系统平台,而MapReduce等运算程序则相当于运行于操作系统之上的应用程序。

YARN基础架构

YARN主要由ResourceManagerNodeManagerApplicationMasterContainer等组件构成。

ResourceManager

ResourceManagerYARN集群的核心组件,负责整体资源的分配和管理。

主要作用如下:

  1. 处理客户端请求。
  2. 监控NodeManager
  3. 启动或监控ApplicationMaster
  4. 资源的分配与调度。

NodeManager

NodeManager是每个集群节点上运行的代理程序。

主要作用如下:

  1. 管理单个节点上的资源。
  2. 处理来自ResourceManager的命令。
  3. 处理来自ApplicationMaster的命令。

ApplicationMaster

用户提交job到集群中时,会ResourceManager会生成一个ApplicationMaster,其是应用程序的主要协调员。

主要作用如下:

  1. 为应用程序申请资源并分配给内部的任务。
  2. 任务的监控与容错。

Container

ContainerYARN中资源的抽象表示。它是一组计算资源(如CPU、内存)的集合,用于执行应用程序中的任务。容器由NodeManager管理,并在节点上启动和运行应用程序的特定实例。

YARN的工作机制

image-20230725221605980

  1. MR程序提交到客户端所在的节点。
  2. YarnRunnerResourceManager申请一个Application
  3. RM将该应用程序的资源路径返回给YarnRunner
  4. 该程序将运行所需资源提交到HDFS上。
  5. 程序资源提交完毕后,申请运行mrAppMaster
  6. RM将用户的请求初始化成一个Task
  7. 其中一个NodeManager领取到Task任务。
  8. NodeManager创建容器Container,并产生MRAppmaster
  9. ContainerHDFS上拷贝资源到本地。
  10. MRAppmasterRM申请运行MapTask资源。
  11. RM将运行MapTask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并创建容器。
  12. MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动MapTaskMapTask对数据分区排序。
  13. MrAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask
  14. ReduceTaskMapTask获取相应分区的数据。
  15. 程序运行完毕后,MR会向RM申请注销自己。

YARN调度器和调度算法

目前,Hadoop作业调度器主要有三种:

  1. FIFO
  2. 容量(Capacity Scheduler
  3. 公平(Fair Scheduler

Apache Hadoop3.1.3默认的资源调度器是Capacity Scheduler

CDH框架默认调度器是Fair Scheduler

具体设置详见:yarn-default.xml文件。

image-20230725222229752

1
2
3
4
5
<property>
<description>The class to use as the resource scheduler.</description>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>

先进先出调度器(FIFO)

FIFO调度器(First In First Out):单队列,根据提交作业的先后顺序,先来先服务。

优点:简单易懂。

缺点:不支持多队列,生产环境很少使用。

容量调度器(Capacity Scheduler)

Capacity SchedulerYahoo开发的多用户调度器。它可以设置多个队列,不同的队列设定不同的资源占比,同一个队列中还可以设置不同用户的资源使用占比和上限。

其优点如下所示:

  1. 多队列:每个队列可配置一定的资源量,每个队列采用FIFO调度策略。
  2. 容量保证:管理员可为每个队列设置资源最低保证和资源使用上限。
  3. 灵活性:如果一个队列中的资源有剩余,可以暂时共享给那些需要资源的队列,而一旦该队列有新的应用程序提交,则其他队列借调的资源会归还给该队列。
  4. 多租户:支持多用户共享集群和多应用程序同时运行。为了防止同一个用户的作业独占队列中的资源,该调度器会对同一用户提交的作业所占资源量进行限定。

公平调度器(Fair Scheduler)

Fair SchedulereFacebook开发的多用户调度器。同队列所有任务共享资源,在时间尺度上获得公平的资源。

与容量调度器相同点:

  1. 多队列:支持多队列多作业。
  2. 容量保证:管理员可为每个队列设置资源最低保证和资源使用上限。
  3. 灵活性:如果一个队列中的资源有剩余,可以暂时共享给那些需要资源的队列,而一旦该队列有新的应用程序提交,则其他队列借调的资源会归还给该队列。
  4. 多租户:支持多用户共享集群和多应用程序同时运行;为了防止同一个用户的作业独占队列中的资源,该调度器会对同一用户提交的作业所占资源量进行限定。

与容量调度器不同点:

  1. 核心调度策略不同:容量调度器优先选择资源利用率低的队列;公平调度器优先选择对资源的缺额比例大的。
  2. 每个队列可以单独设置资源分配方式:容量调度器FIFODRF;公平调度器FIFOFAIRDRF

YARN案例实操

YARN生产环境核心参数配置案例

需求:从1T数据中,统计每个单词出现的次数。

硬件资源:3台服务器,每台配置4G内存,4CPU4线程。

增加yarn-site.xml配置参数

为了演示效果,首先我们把修改前的YARN中硬件参数截图如下所示:

image-20230725223633535

增加yarn-site.xml配置参数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<!-- 选择调度器,默认容量 -->
<property>
<description>The class to use as the resource scheduler.</description>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>

<!-- ResourceManager处理调度器请求的线程数量,默认50;如果提交的任务数大于50,可以增加该值,但是不能超过3台 * 4线程 = 12线程(去除其他应用程序实际不能超过8) -->
<property>
<description>Number of threads to handle scheduler interface.</description>
<name>yarn.resourcemanager.scheduler.client.thread-count</name>
<value>8</value>
</property>


<!--
是否将虚拟核数当作CPU核数,默认是false,采用物理CPU核数
-->
<property>
<description>Flag to determine if logical processors(such as
hyperthreads) should be counted as cores. Only applicable on Linux
when yarn.nodemanager.resource.cpu-vcores is set to -1 and
yarn.nodemanager.resource.detect-hardware-capabilities is true.
</description>
<name>yarn.nodemanager.resource.count-logical-processors-as-cores</name>
<value>false</value>
</property>

<!-- 是否让yarn自动检测硬件进行配置,默认是false,如果该节点有很多其他应用程序,建议手动配置。如果该节点没有其他应用程序,可以采用自动 -->
<property>
<description>Enable auto-detection of node capabilities such as
memory and CPU.
</description>
<name>yarn.nodemanager.resource.detect-hardware-capabilities</name>
<value>false</value>
</property>


<!--
Core转成Vcore的个数(虚拟核数和物理核数乘数,默认是1.0)
hadoop中的vcore不是真正的core,通常vcore的个数设置为逻辑cpu个数的1~5倍。
-->
<property>
<description>Multiplier to determine how to convert phyiscal cores to vcores. This value is used if
yarn.nodemanager.resource.cpu-vcores is set to -1(which implies auto-calculate vcores) and
yarn.nodemanager.resource.detect-hardware-capabilities is set to true. The number of vcores will be calculated as number of CPUs * multiplier.
</description>
<name>yarn.nodemanager.resource.pcores-vcores-multiplier</name>
<value>1.0</value>
</property>

<!-- NodeManager使用内存数,默认8G,修改为4G内存 -->
<property>
<description>Amount of physical memory, in MB, that can be allocated
for containers. If set to -1 and
yarn.nodemanager.resource.detect-hardware-capabilities is true, it is
automatically calculated(in case of Windows and Linux).
In other cases, the default is 8192MB.
</description>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>4096</value>
</property>

<!-- nodemanager的CPU核数,不按照硬件环境自动设定时默认是8个,修改为4个 -->
<property>
<description>Number of vcores that can be allocated
for containers. This is used by the RM scheduler when allocating
resources for containers. This is not used to limit the number of
CPUs used by YARN containers. If it is set to -1 and
yarn.nodemanager.resource.detect-hardware-capabilities is true, it is
automatically determined from the hardware in case of Windows and Linux.
In other cases, number of vcores is 8 by default.</description>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>4</value>
</property>

<!-- 容器最小内存,默认1G -->
<property>
<description>The minimum allocation for every container request at the RM in MBs. Memory requests lower than this will be set to the value of this property. Additionally, a node manager that is configured to have less memory than this value will be shut down by the resource manager.
</description>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>1024</value>
</property>

<!-- 容器最大内存,默认8G,修改为2G -->
<property>
<description>The maximum allocation for every container request at the RM in MBs. Memory requests higher than this will throw an InvalidResourceRequestException.
</description>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>2048</value>
</property>

<!-- 容器最小CPU核数,默认1个 -->
<property>
<description>The minimum allocation for every container request at the RM in terms of virtual CPU cores. Requests lower than this will be set to the value of this property. Additionally, a node manager that is configured to have fewer virtual cores than this value will be shut down by the resource manager.
</description>
<name>yarn.scheduler.minimum-allocation-vcores</name>
<value>1</value>
</property>

<!-- 容器最大CPU核数,默认4个,修改为2个 -->
<property>
<description>The maximum allocation for every container request at the RM in terms of virtual CPU cores. Requests higher than this will throw an
InvalidResourceRequestException.</description>
<name>yarn.scheduler.maximum-allocation-vcores</name>
<value>2</value>
</property>

<!-- 虚拟内存检查,默认打开,修改为关闭 -->
<property>
<description>Whether virtual memory limits will be enforced for
containers.</description>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>

<!-- 虚拟内存和物理内存设置比例,默认2.1 -->
<property>
<description>Ratio between virtual memory to physical memory when setting memory limits for containers. Container allocations are expressed in terms of physical memory, and virtual memory usage is allowed to exceed this allocation by this ratio.
</description>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>2.1</value>
</property>

然后分发配置:

1
xsync yarn-site.xml

image-20230725223938629

然后重启集群

1
2
myhadoop stop
myhadoop start

image-20230725224042051

再次查看YARN的配置信息。

image-20230725224128154

这个时候可以看到以下变化:

  1. 最大内存变成了12GB
  2. 最大VCORE变成了12
  3. 最大资源使用量变成了2G+2Core

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

  1. 在生产环境怎么创建队列?
    • 调度器默认就1个default队列,不能满足生产要求。
    • 按照框架:hive /spark/ flink 每个框架的任务放入指定的队列(企业用的不是特别多)。
    • 按照业务模块:登录注册、购物车、下单、业务部门1、业务部门2。创建多队列的好处?
  2. 创建多队列的好处?
    • 因为担心员工不小心,写递归死循环代码,把所有资源全部耗尽。
    • 实现任务的降级使用,特殊时期保证重要的任务队列资源充足。(例如:淘宝在双11618

业务部门1(重要) => 业务部门2(比较重要) => 下单(一般) => 购物车(一般) => 登录注册(次要)。

配置多队列的容量调度器

需求:default队列占总内存的40%,最大资源容量占总资源60%hive队列占总内存的60%,最大资源容量占总资源80%

点击YARNweb界面中的Scheduler,查看当前队列情况。

image-20230725225056137

此时,只有一个默认队列default

  1. capacity-scheduler.xml中配置如下:

    修改内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <!-- 指定多队列,增加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>

    增加内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    <!-- 指定hive队列的资源额定容量 -->
    <property>
    <name>yarn.scheduler.capacity.root.hive.capacity</name>
    <value>60</value>
    </property>

    <!-- 用户最多可以使用队列多少资源,1表示所有 -->
    <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>

    <!-- 启动hive队列 -->
    <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>

    <!-- 任务的超时时间设置:yarn application -appId appId -updateLifetime Timeout
    参考资料:https://blog.cloudera.com/enforcing-application-lifetime-slas-yarn/ -->

    <!-- 如果application指定了超时时间,则提交到该队列的application能够指定的最大超时时间不能超过该值。
    -->
    <property>
    <name>yarn.scheduler.capacity.root.hive.maximum-application-lifetime</name>
    <value>-1</value>
    </property>

    <!-- 如果application没指定超时时间,则用default-application-lifetime作为默认值 -->
    <property>
    <name>yarn.scheduler.capacity.root.hive.default-application-lifetime</name>
    <value>-1</value>
    </property>
  2. 分发配置

    1
    xsync capacity-scheduler.xml

    image-20230725224853194

  3. hadoop103节点,重启YARN,或执行以下命令刷新队列。

    1
    yarn rmadmin -refreshQueues

    这个时候再次刷新YARNWEB界面。

    image-20230725225313833

    可以看到此时就有了两个队列hivedefault

向hive队列提交任务

向指定队列提交任务有两种方式:

  1. 打包jar然后上传到节点执行,使用以下方法指定提交的队列。

    1
    hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount -D mapreduce.job.queuename=hive /input /output

    这里使用的是Hadoop中的官方案例进行实现。

    image-20230725231745746

    开始运行后,再次回到YARNWEB界面可以看到,现在已经开始使用hive队列的资源执行任务了。

  2. 在本地中Driver类中,设置conf中的参数。

    1
    2
    // 设置如下内容 
    conf.set("mapreduce.job.queuename","hive");

    image-20230725231932732

    设置完后点击package进行打包。

    1
    hadoop jar  /input /output

    上传到集群后,执行以下代码在hadoop中运行jar包。由于此时在打包jar包时就已经指定了提交的队列为hive

    1
    hadoop jar MRDemo-1.0-SNAPSHOT.jar com.tipdm.mr.wordcount.WCDriver2 /input /output2

    开始执行任务后,同样可以在hive这个队列中提交任务。

    image-20230725232118413

同时向集群中提交两个任务

这个时候将上述两个任务同时在集群中提交,一个指定的队列为默认队列default,一个指定的队列为hive队列。

首先将集群中的输入文件夹全部删除,然后在hadoop102hadoop103中分别执行以下代码。

1
hadoop jar MRDemo-1.0-SNAPSHOT.jar com.tipdm.mr.wordcount.WCDriver2 /input /output2
1
hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input /output

这个时候再次查看YARN中的结果,可以看到defaluthive这两个队列均有任务在执行。

image-20230725232924070

演示资源借调

为了演示这个效果,从前面的运行结果可以看到,WCCount这个任务的资源占用是高于10%的,现在我们再次修改capacity-scheduler.xml配置文件,将hive队列中的默认资源占用设置为10%defalut90%

修改内容如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 降低default队列资源额定容量为90%,默认100% -->
<property>
<name>yarn.scheduler.capacity.root.default.capacity</name>
<value>90</value>
</property>
<!-- 设置default队列资源最大容量为100% -->
<property>
<name>yarn.scheduler.capacity.root.default.maximum-capacity</name>
<value>100</value>
</property>
<!-- 指定hive队列的资源额定容量 -->
<property>
<name>yarn.scheduler.capacity.root.hive.capacity</name>
<value>10</value>
</property>

然后分发任务:

1
xsync capacity-scheduler.xml

image-20230725233533587

重启ResourceManager

1
2
yarn --daemon stop resourcemanager
yarn --daemon start resourcemanager

image-20230725233812800

然后再次提交任务

1
hadoop jar MRDemo-1.0-SNAPSHOT.jar com.tipdm.mr.wordcount.WCDriver2 /input /output22

这个时候虽然任务也是可以进行的,但是此时在YARNWEB界面显示的是橙色的进度条,表示超出设定的容量,开始向其他空闲队列借调资源执行任务。

image-20230725233924883

-------------本文结束感谢您的阅读-------------