简介
在古老的埃及,法老的宫殿宏伟壮丽,彰显着王国的强盛与繁荣。然而,在金碧辉煌的表象之下,一场危机正在酝酿。法老的庞大粮仓堆满了尼罗河馈赠的物产,却管理混乱。负责分配资源的祭司难以应对民众的需求。
这时,年轻而聪慧的祭司阿蒙霍特普(Amenhotep)登场了。法老委派他整顿王国的资源管理。他的任务是设计一套系统,确保珍贵物资得到公平、高效的分配,让每位民众都能获得应得的份额。
法老赏识阿蒙霍特普的才智与尽责,准许他使用最新的技术成果——Hadoop YARN(Yet Another Resource Negotiator)系统。借助这一强大的工具,阿蒙霍特普开始学习 YARN 的关键组件之一:调度器,以实现自己的目标。
了解 Hadoop YARN 调度器
本步骤将介绍 Hadoop YARN 中的不同调度策略,并检查当前正在运行的调度器。
首先,切换到 Hadoop 用户。在本实验中,请在当前终端中运行所有命令:
su - hadoop
明确指定配置目录。在此镜像中,Hadoop 安装在 /home/hadoop/hadoop;系统不使用 /etc/hadoop/conf。
export HADOOP_CONF_DIR=/home/hadoop/hadoop/etc/hadoop
Hadoop YARN 支持 Fair Scheduler 和 Capacity Scheduler。Fair Scheduler 会随时间在应用程序之间共享资源,队列权重会影响各队列所占的相对份额。Capacity Scheduler 会按层级为队列分配有保障的容量,同时允许队列共享未使用的资源。
Hadoop 3.3.6 没有提供 yarn scheduler 子命令。请查询 ResourceManager 的 REST API,检查实际正在运行的调度器,而不要仅凭配置文件推断调度器已生效。先保存 API 响应:
curl -fsS --retry 15 --retry-connrefused --retry-delay 1 http://localhost:8088/ws/v1/cluster/scheduler -o /home/hadoop/scheduler-initial.json
显示当前调度器的类型:
python3 - <<'PY'
import json
with open('/home/hadoop/scheduler-initial.json') as stream:
info = json.load(stream)['scheduler']['schedulerInfo']
print(info['type'])
PY
在全新实验环境中,预期输出如下:
capacityScheduler
保留此终端,后续步骤还会用到。我们将通过 Hadoop 配置文件配置各个调度器,并重启 ResourceManager,使其加载选定的调度器类。
配置 Fair Scheduler
本步骤将配置 Fair Scheduler,在 citizens 和 priests 队列之间共享资源。
以 Hadoop 用户身份运行以下完整代码块,创建分配配置文件:
cat > /home/hadoop/fair-scheduler.xml <<'XML'
<?xml version="1.0"?>
<allocations>
<defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>
<queue name="root">
<weight>1.0</weight>
<queue name="citizens">
<weight>1.0</weight>
<minResources>1024 mb, 1 vcores</minResources>
</queue>
<queue name="priests">
<weight>2.0</weight>
<minResources>2048 mb, 2 vcores</minResources>
</queue>
</queue>
</allocations>
XML
citizens 队列的权重为 1,最低资源量为 1024 MB 内存和 1 个 vcore。priests 队列的权重为 2,最低资源量为 2048 MB 内存和 2 个 vcore。最低资源量是资源目标,实际分配受集群可用资源限制;权重则会影响剩余资源的共享方式。
在 yarn-site.xml 中选择 Fair Scheduler,并指定分配配置文件。以下命令会保留现有的 NodeManager 设置:
python3 - <<'PY'
import os
import xml.etree.ElementTree as ET
path = os.path.join(os.environ['HADOOP_CONF_DIR'], 'yarn-site.xml')
tree = ET.parse(path)
root = tree.getroot()
settings = {
'yarn.resourcemanager.scheduler.class':
'org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler',
'yarn.scheduler.fair.allocation.file': '/home/hadoop/fair-scheduler.xml',
}
for name, value in settings.items():
prop = next((p for p in root.findall('property') if p.findtext('name') == name), None)
if prop is None:
prop = ET.SubElement(root, 'property')
ET.SubElement(prop, 'name').text = name
ET.SubElement(prop, 'value')
prop.find('value').text = value
tree.write(path, encoding='UTF-8', xml_declaration=True)
PY
更改调度器类需要重启 ResourceManager。本实验集群中没有正在运行的应用程序,因此只需停止并启动 ResourceManager:
yarn --daemon stop resourcemanager
yarn --daemon start resourcemanager
再次查询当前运行的调度器。重试选项会留出时间供 ResourceManager 启动;启动期间可能会短暂出现连接错误。
curl -fsS --retry 15 --retry-connrefused --retry-delay 1 http://localhost:8088/ws/v1/cluster/scheduler -o /home/hadoop/scheduler-fair.json
python3 - <<'PY'
import json
with open('/home/hadoop/scheduler-fair.json') as stream:
info = json.load(stream)['scheduler']['schedulerInfo']
print(info['type'])
for queue in info['rootQueue']['childQueues']['queue']:
if queue['queueName'] in ('root.citizens', 'root.priests'):
resources = queue['minResources']
print(queue['queueName'], resources['memory'], resources['vCores'])
PY
预期输出如下(队列顺序可能不同):
fairScheduler
root.citizens 1024 1
root.priests 2048 2
请先完成本步骤的检查,再在步骤 3 中切换调度器。
配置 Capacity Scheduler
本步骤将切换到 Capacity Scheduler,并为每个队列分配 50% 的集群容量。
以 Hadoop 用户身份将 capacity-scheduler.xml 直接写入 Hadoop 配置目录。仅将文件保存在 /home/hadoop 中,调度器不会加载它:
cat > /home/hadoop/hadoop/etc/hadoop/capacity-scheduler.xml <<'XML'
<?xml version="1.0"?>
<configuration>
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>citizens,priests</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.citizens.capacity</name>
<value>50</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.priests.capacity</name>
<value>50</value>
</property>
</configuration>
XML
两个子队列的容量总和为 100%。在 yarn-site.xml 中选择 Capacity Scheduler:
sed -i 's/org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler/org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler/' /home/hadoop/hadoop/etc/hadoop/yarn-site.xml
重启 ResourceManager,使其加载新的调度器类和队列配置:
yarn --daemon stop resourcemanager
yarn --daemon start resourcemanager
检查当前调度器及其队列:
curl -fsS --retry 15 --retry-connrefused --retry-delay 1 http://localhost:8088/ws/v1/cluster/scheduler -o /home/hadoop/scheduler-capacity.json
python3 - <<'PY'
import json
with open('/home/hadoop/scheduler-capacity.json') as stream:
info = json.load(stream)['scheduler']['schedulerInfo']
print(info['type'])
for queue in info['queues']['queue']:
print(queue['queueName'], queue['capacity'])
PY
预期输出如下(队列顺序可能不同):
capacityScheduler
citizens 50.0
priests 50.0
当两个队列都需要资源时,每个队列都有 50% 的保障容量。队列可以共享未使用的容量;这些数值不会强制空闲资源一直闲置。
总结
在本实验中,我们学习了如何配置并应用 Hadoop YARN 的不同调度策略,以有效管理资源分配。掌握 Fair Scheduler 和 Capacity Scheduler 后,阿蒙霍特普就能确保王国的民众公平地共享资源,同时优先保障祭司执行的重要任务。
通过亲手操作,我们进一步了解了 Hadoop YARN 的强大功能,以及它在复杂环境中管理资源的能力。将本实验学到的知识应用到实际工作中,我们可以根据组织的具体需求,构建高效、公平的资源管理系统。



