1. 理解YARN:大数据时代的资源调度中枢
第一次接触YARN是在2015年处理电商平台用户行为日志时。当时我们的MapReduce作业频繁出现资源争抢,整个集群效率低下。直到将Hadoop 1.0升级到2.x版本引入YARN后,集群资源利用率直接从40%提升到75%以上。这种质的飞跃让我意识到,要真正玩转大数据,必须吃透YARN这套资源管理系统。
YARN(Yet Another Resource Negotiator)不是简单的升级,而是Hadoop架构的一次革命。在传统MapReduce架构中,JobTracker既要管作业调度又要管资源分配,这种"大包大揽"的设计导致扩展性差、资源利用率低。YARN通过将这两大功能解耦,实现了真正的分布式资源管理。
举个生活中的例子:旧架构就像一个小餐馆,老板既要接单又要炒菜;而YARN架构则像现代化餐厅,前台接待(ResourceManager)、后厨调度(NodeManager)、服务员(ApplicationMaster)各司其职。这种专业化分工让系统能轻松应对高峰期的客流(大数据作业)。
2. YARN架构深度解析
2.1 核心组件协作机制
YARN采用主从架构,主要包含三个核心组件:
-
ResourceManager(RM):集群资源的最高仲裁者,包含:
- Scheduler:纯调度器,只负责分配资源
- ApplicationsManager:负责接收作业提交、协调执行
-
NodeManager(NM):每个节点上的"工头",负责:
- 容器(Container)生命周期管理
- 监控资源使用情况(CPU、内存等)
- 向RM汇报心跳和资源状态
-
ApplicationMaster(AM):每个应用特有的"项目经理",负责:
- 向RM申请资源
- 与NM协作启动/监控任务
- 容错处理
java复制// 典型YARN应用提交代码片段
Configuration conf = new YarnConfiguration();
YarnClient yarnClient = YarnClient.createYarnClient();
yarnClient.init(conf);
yarnClient.start();
ApplicationSubmissionContext appContext = yarnClient
.createApplication()
.getApplicationSubmissionContext();
appContext.setApplicationName("My-YARN-App");
2.2 资源请求与分配流程
- 客户端提交应用到RM
- RM分配第一个Container给AM
- AM向RM注册并定期发送心跳
- AM根据需求发送资源请求(ResourceRequest)
- RM的Scheduler分配资源
- AM在NM上启动任务
- 任务执行期间AM监控状态
- 任务完成后AM注销退出
关键点:YARN采用pull-based模型,AM主动请求资源而非被动分配,这种设计大幅提升了灵活性。
2.3 资源模型详解
YARN使用[memory,vcores]二维资源模型:
- 内存:物理内存+虚拟内存限制
- vcores:虚拟CPU核数,不绑定物理核心
配置示例(yarn-site.xml):
xml复制<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>16384</value> <!-- 16GB可用内存 -->
</property>
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>8</value> <!-- 8个虚拟核 -->
</property>
3. 实战:YARN资源调度配置
3.1 调度器选型对比
| 调度器类型 | 特点 | 适用场景 | 配置参数示例 |
|---|---|---|---|
| FIFO | 简单先进先出 | 测试环境 | yarn.resourcemanager.scheduler.class=org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler |
| Capacity | 队列间隔离保障 | 多租户环境 | yarn.scheduler.capacity.root.queues=dev,prod |
| Fair | 动态平衡资源 | 混合负载 | yarn.resourcemanager.scheduler.class=org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler |
3.2 容量调度器配置实战
- 创建调度队列:
xml复制<!-- capacity-scheduler.xml -->
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>analytics,batch</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.analytics.capacity</name>
<value>60</value>
</property>
- 设置队列限制:
bash复制# 限制单个用户资源使用
yarn.scheduler.capacity.root.analytics.user-limit-factor=2
- 配置ACL访问控制:
xml复制<property>
<name>yarn.scheduler.capacity.root.analytics.acl_submit_applications</name>
<value>data_team</value>
</property>
3.3 资源隔离实践
内存隔离:
xml复制<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>2.1</value>
</property>
CPU隔离(Linux容器):
bash复制yarn.nodemanager.resource.percentage-physical-cpu-limit=100
yarn.nodemanager.linux-container-executor.cgroups.mount=true
4. YARN应用开发实战
4.1 编写自定义AM
java复制public class MyAM extends ApplicationMaster {
@Override
protected void serviceInit(Configuration conf) throws Exception {
// 初始化AM
registerAM(conf);
}
private void registerAM(Configuration conf) {
AMRMClient<ContainerRequest> rmClient = AMRMClient.createAMRMClient();
rmClient.init(conf);
rmClient.start();
// 注册应用Master
rmClient.registerApplicationMaster("", 0, "");
}
}
4.2 资源请求策略
java复制// 优先级设置
Priority priority = Records.newRecord(Priority.class);
priority.setPriority(0);
// 资源描述
Resource capability = Records.newRecord(Resource.class);
capability.setMemorySize(2048); // 2GB
capability.setVirtualCores(1); // 1vcore
// 创建资源请求
ContainerRequest request = new ContainerRequest(
capability, null, null, priority);
rmClient.addContainerRequest(request);
4.3 容器启动与管理
java复制// 启动容器回调
new NMClientAsync.CallbackHandler() {
@Override
public void onContainerStarted(ContainerId containerId,
Map<String, ByteBuffer> allServiceResponse) {
LOG.info("Container started: " + containerId);
}
@Override
public void onContainerStatusReceived(ContainerId containerId,
ContainerStatus containerStatus) {
// 处理容器状态更新
}
};
5. 性能调优与问题排查
5.1 常见性能瓶颈
-
AM单点问题:
- 现象:AM成为性能瓶颈
- 解决方案:拆分大作业为小作业,使用AM池
-
资源碎片化:
- 现象:集群显示有资源但作业卡住
- 调优:调整scheduler.minimum-allocation-mb/vcores
-
NM资源超售:
- 现象:节点负载过高
- 配置:yarn.nodemanager.resource.memory-mb不超过物理内存80%
5.2 监控指标解析
关键JMX指标:
- QueueMetrics:AvailableMB
- ClusterMetrics:NumActiveNMs
- SchedulerMetrics:AllocatedContainers
Grafana监控模板配置示例:
json复制{
"panels": [{
"title": "集群内存使用",
"targets": [{
"expr": "sum(yarn_cluster_availableMB) / sum(yarn_cluster_totalMB) * 100",
"legendFormat": "内存利用率"
}]
}]
}
5.3 典型错误处理
问题1:AM注册失败
- 检查点:
- RM日志中的AM认证记录
- AM尝试连接的RM地址是否正确
- 网络连通性(telnet RM地址 8030)
问题2:Container启动超时
- 排查步骤:
- 检查NM日志中的资源可用性
- 验证容器启动脚本权限
- 检查yarn.nodemanager.local-dirs磁盘空间
问题3:资源分配不均衡
- 调优方案:
xml复制<property> <name>yarn.scheduler.fair.assignmultiple</name> <value>true</value> </property> <property> <name>yarn.scheduler.fair.dynamic.max.assign</name> <value>5</value> </property>
6. 进阶:YARN与云原生整合
6.1 Kubernetes集成方案
YARN on K8s架构:
code复制+---------------+ +-----------------+
| YARN RM | | K8s Master |
+-------+-------+ +--------+--------+
| |
+-------+-------+ +--------+--------+
| YARN NM | | K8s Node |
| (DaemonSet) | | (with YARN Pod) |
+---------------+ +-----------------+
关键配置:
yaml复制# yarn-k8s部署描述
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: yarn-nm
spec:
template:
spec:
containers:
- name: nodemanager
image: hadoop-yarn-nm:3.3.1
resources:
requests:
memory: "512Mi"
cpu: "500m"
6.2 混合调度实践
通过YARN Federation实现跨集群调度:
- 配置多个子集群
- 设置路由策略(如负载均衡)
- 统一资源视图管理
xml复制<!-- federation配置示例 -->
<property>
<name>yarn.federation.policy-manager</name>
<value>org.apache.hadoop.yarn.server.federation.policies.manager.WeightedPolicyManager</value>
</property>
<property>
<name>yarn.federation.subcluster1.address</name>
<value>rm1.cluster:8032</value>
</property>
7. 生产环境最佳实践
7.1 安全加固方案
-
认证集成:
xml复制<property> <name>yarn.resourcemanager.principal</name> <value>yarn/_HOST@REALM</value> </property> -
网络隔离:
- 使用Linux网络命名空间
- 配置yarn.nodemanager.runtime.linux.network-groups
-
日志审计:
bash复制
yarn.log-aggregation.retain-seconds=604800 yarn.log.server.url=http://logserver:19888
7.2 资源配额管理
通过cgroups实现精细控制:
bash复制# 设置CPU限制
yarn.nodemanager.linux-container-executor.cgroups.hierarchy=/yarn
yarn.nodemanager.linux-container-executor.cgroups.mount-path=/sys/fs/cgroup
7.3 灾备与高可用
RM HA配置要点:
- 启用ZKFC:
xml复制<property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> - 设置ZK集群:
xml复制<property> <name>yarn.resourcemanager.zk-address</name> <value>zk1:2181,zk2:2181,zk3:2181</value> </property>
在金融行业的生产实践中,我们发现YARN配置需要特别注意以下几点:
- 资源超配比例不超过1.2:1
- AM重启次数限制在3次以内
- 关键业务队列设置最小资源保障
- 定期清理完成的应用记录(yarn.resourcemanager.max-completed-applications=1000)