一、YARN资源调度器那些事儿

说到大数据集群的资源管理,YARN就像是个操碎了心的老管家。每天要处理各种计算任务来要资源,MapReduce要内存,Spark要CPU,Flink又要两者兼顾。这时候如果调度器没配置好,就会出现资源浪费或者任务饿死的尴尬局面。

举个真实案例:某电商公司的大促期间,集群CPU利用率长期在30%徘徊,但业务部门还在抱怨任务排队。后来发现是Fair Scheduler的maxResources参数设置得太保守,导致单个队列的资源上限成了瓶颈。这就好比明明家里有十个房间,却规定每个客人最多只能住两间。

技术栈:Hadoop 3.3.1 YARN

<!-- 公平调度器配置示例 -->
<allocations>
  <!-- 电商订单队列设置 -->
  <queue name="order">
    <minResources>10000 mb, 20 vcores</minResources>
    <maxResources>50000 mb, 100 vcores</maxResources>
    <maxRunningApps>50</maxRunningApps>
    <weight>2.0</weight>
    <!-- 权重设置让订单队列获得双倍资源 -->
  </queue>
  
  <!-- 数据分析队列 -->
  <queue name="analysis">
    <minResources>5000 mb, 10 vcores</minResources>
    <maxResources>30000 mb, 50 vcores</maxResources>
    <schedulingPolicy>fair</schedulingPolicy>
    <!-- 采用公平策略而非FIFO -->
  </queue>
</allocations>

二、调度算法选型指南

YARN主要有三种调度模式:FIFO就像独裁者,Capacity像计划经济,Fair像市场经济。根据我们多年踩坑经验,Fair Scheduler在90%的场景下都是最佳选择,特别是当你的业务有以下特征时:

  1. 任务类型多样(有长有短)
  2. 资源需求波动大
  3. 多个团队共享集群

技术栈:Hadoop 3.x

// 通过YARN API动态调整队列配置示例
public void updateQueueConfig() throws Exception {
  YarnClient client = YarnClient.createYarnClient();
  client.init(new Configuration());
  client.start();
  
  // 获取当前调度配置
  QueueInfo queueInfo = client.getQueueInfo("order");
  
  // 动态调整最大资源
  Resource newMax = Resource.newInstance(
    60000, // 内存MB
    120    // vCores
  );
  
  // 提交修改请求
  client.updateQueueConfig(new QueueConfigInfo(
    "order", 
    newMax,
    queueInfo.getMinResources()
  ));
}

三、参数调优实战手册

下面这些参数就像汽车的油门和刹车,调得好能让你的集群飞起来:

内存相关参数

  • yarn.scheduler.minimum-allocation-mb:建议设为1-2GB
  • yarn.scheduler.maximum-allocation-mb:不要超过单节点物理内存的80%

CPU相关魔法

  • yarn.scheduler.increment-allocation-vcores:设置为1
  • yarn.nodemanager.resource.percentage-physical-cpu-limit:建议70-90%

技术栈:YARN + Linux cgroups

# 查看实际资源使用情况的Shell脚本
#!/bin/bash

# 获取所有NodeManager节点
nodes=$(yarn node -list | grep RUNNING | awk '{print $1}')

for node in $nodes
do
  echo "===== $node ====="
  ssh $node "
    # 内存使用统计
    free -m | awk 'NR==2{printf \"Mem: %.2f%% used\\n\", $3*100/$2}'
    
    # CPU使用统计
    top -bn1 | grep 'Cpu(s)' | sed 's/.*, *\([0-9.]*\)%id.*/\1/' | 
      awk '{printf \"CPU: %.2f%% used\\n\", 100-$1}'
  "
done

四、避坑指南与高阶技巧

见过太多人掉进这些坑里了:

  1. 资源碎片问题:就像拼图游戏,剩余的小块内存可能永远找不到匹配的任务。解决方案是设置合理的增量值:

    <property>
      <name>yarn.scheduler.increment-allocation-mb</name>
      <value>512</value>  <!-- 内存分配最小单位设为512MB -->
    </property>
    
  2. 队列死锁:当两个队列互相等待对方释放资源时,可以设置抢占策略:

    <property>
      <name>yarn.scheduler.fair.preemption</name>
      <value>true</value>
      <description>启用资源抢占</description>
    </property>
    
  3. 动态资源发现:在云环境特别有用

    // 动态发现新节点的示例代码
    ResourceTrackerService.addNewNode(
      NodeId.newInstance("new-node-ip", 8041),
      Resource.newInstance(128000, 32) // 128G内存,32核
    );
    

五、未来演进方向

随着Kubernetes的兴起,YARN也在进化。新版本已经支持Docker容器化任务,这就像给老管家配上了智能机器人助手:

<property>
  <name>yarn.nodemanager.container-executor.class</name>
  <value>org.apache.hadoop.yarn.server.nodemanager.DockerContainerExecutor</value>
</property>
<property>
  <name>yarn.nodemanager.docker.image</name>
  <value>hadoop:3.3.1</value>  <!-- 统一的基础镜像 -->
</property>

不过要注意,容器化会带来约5-10%的性能开销,但对资源隔离性的提升是值得的。

总结时刻

经过这些年的实践,我们总结出YARN调优的黄金法则:监控要实时、配置要弹性、队列要隔离、参数要渐进。记住,没有放之四海而皆准的最优配置,就像没有适合所有人的鞋子。建议先用小规模集群做AB测试,观察两周内的资源利用率曲线,再逐步推广到全集群。

最后送大家一个检查清单:

  1. 是否开启了资源监控?
  2. 队列划分是否符合业务特征?
  3. 最小/最大资源设置是否合理?
  4. 是否有设置抢占策略?
  5. 是否定期review配置?