第4章:资源管理与调度:YARN架构与容器化演进

资源管理与调度,说白了就是大数据集群的「管家」。我做了这么多年架构,见过太多集群因为资源管理不当而崩溃的例子。今天咱们就聊聊YARN和Kubernetes这两大调度系统。

4.1 YARN架构:ResourceManager与NodeManager

YARN是Hadoop生态的老牌资源管理器。它的核心思想很简单:把资源管理和作业调度分开。

4.1.1 核心组件

  • ResourceManager(RM):全局资源调度的大脑。负责接收客户端请求,分配资源给各个应用。
  • NodeManager(NM):每台机器上的代理。负责监控本机资源(CPU、内存、磁盘),并向RM汇报。
  • ApplicationMaster(AM):每个应用的管理者。负责向RM申请资源,并协调任务执行。
  • Container:YARN中的资源抽象单位。说白了就是一个「资源盒子」,里面封装了CPU、内存等。

重要概念:YARN的Container和Docker的Container不是一回事。YARN的Container只是一个资源分配的逻辑单位,而Docker的Container是完整的运行环境。

4.1.2 调度流程

我简单描述一下作业提交的完整流程:

  1. 客户端提交作业到ResourceManager
  2. RM在某个NodeManager上启动一个Container,运行ApplicationMaster
  3. AM向RM注册,并申请更多资源
  4. RM分配资源,AM在对应的NodeManager上启动任务Container
  5. 任务执行过程中,AM持续监控进度
  6. 任务完成后,AM向RM注销,释放所有资源

个人经验:我在项目中遇到过一个问题——AM申请资源时总是超时。后来发现是RM的调度器配置了FIFO策略,导致大作业把资源全占了。换成Capacity Scheduler后,问题就解决了。

4.1.3 调度策略对比

调度器 特点 适用场景
FIFO Scheduler 先来先服务,简单粗暴 单用户、小集群
Capacity Scheduler 按队列分配资源,支持多租户 多部门共享集群
Fair Scheduler 公平分配,作业间动态调整 资源竞争激烈的场景

我个人习惯用Capacity Scheduler。为什么呢?因为它能保证每个队列的最低资源,又允许队列间资源共享。你想想看,如果A部门突然有紧急任务,可以临时借用B部门的空闲资源,多灵活。

4.2 容器化演进:从Docker到Kubernetes

YARN虽然好用,但有个硬伤——它只管理CPU和内存。对于GPU、网络带宽这些资源,支持得很差。而且YARN的Container隔离性也不够强。

这时候,Docker和Kubernetes就登场了。

4.2.1 Docker:轻量级容器

Docker解决了「在我机器上能跑」的问题。它把应用和依赖打包成一个镜像,走到哪都能跑。

# 一个简单的Dockerfile示例
FROM centos:7
RUN yum install -y java-1.8.0-openjdk
COPY myapp.jar /opt/
CMD ["java", "-jar", "/opt/myapp.jar"]

避坑指南:我曾经在Docker镜像里装了一堆不必要的包,结果镜像体积从200MB膨胀到2GB。后来我学会了用多阶段构建,只保留运行时需要的文件。镜像小了,部署速度也快了。

4.2.2 Kubernetes:容器编排平台

Docker解决了单机问题,但集群管理怎么办?Kubernetes就是干这个的。

Kubernetes的核心概念:

  • Pod:最小的调度单元。一个Pod可以包含一个或多个容器。
  • Node:集群中的工作节点。
  • Deployment:管理Pod的副本数和滚动更新。
  • Service:提供稳定的网络访问入口。

4.3 Kubernetes调度器与Pod设计

Kubernetes的调度器,说白了就是决定Pod该放到哪个Node上运行。

4.3.1 调度流程

  1. 过滤阶段:排除不满足条件的Node(比如资源不足、端口冲突)。
  2. 打分阶段:对剩余Node进行评分,选出最优的。
  3. 绑定阶段:将Pod绑定到选中的Node上。

默认的调度器用的是「最小化资源碎片」策略。但实际项目中,我们经常需要自定义调度策略。

# 自定义调度器配置示例
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: my-scheduler
    plugins:
      score:
        enabled:
          - name: NodeResourcesBalancedAllocation
            weight: 3
          - name: NodeResourcesLeastAllocated
            weight: 1

核心要点:Pod设计时,要合理设置资源请求(requests)和限制(limits)。requests是保证能拿到的资源,limits是允许使用的上限。我建议requests设得保守一些,limits设得宽松一些。

4.3.2 Pod设计最佳实践

嗯,这里要注意几个关键点:

  • 亲和性调度:把相关的Pod调度到同一台机器上,减少网络延迟。
  • 反亲和性调度:把关键服务的Pod分散到不同机器上,避免单点故障。
  • 资源预留:系统组件(如日志收集、监控代理)要预留资源,别被业务Pod挤占。
# Pod亲和性配置示例
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
              - key: app
                operator: In
                values:
                  - my-app
          topologyKey: "kubernetes.io/hostname"

4.3.3 从YARN到Kubernetes的迁移

我最近在做一个项目,就是把Spark作业从YARN迁移到Kubernetes上。为什么要迁移?因为Kubernetes的资源利用率更高,而且支持GPU等异构资源。

迁移过程中遇到几个坑:

  • YARN的Container是长期运行的,而Kubernetes的Pod是临时性的。需要调整Spark的配置。
  • YARN有队列机制,Kubernetes用Namespace和ResourceQuota来实现类似功能。
  • 网络方面,YARN用host网络,Kubernetes用CNI插件。需要重新规划网络策略。

个人建议:如果你正在做迁移,先从小规模的非核心作业开始。我当初就是先迁移了几个离线报表作业,跑了一周没问题,才逐步扩大范围。

4.4 总结

资源管理与调度,是大数据平台的基石。YARN适合传统的Hadoop生态,Kubernetes则更适合云原生场景。我个人预测,未来3-5年,Kubernetes会逐步取代YARN成为主流。

但话说回来,技术选型没有银弹。如果你的团队对YARN很熟悉,业务也稳定,没必要强行迁移。如果你们正在建设新平台,那Kubernetes绝对是更好的选择。

下一章,咱们聊聊数据存储与计算引擎的选型。到时候我会分享一些实际项目中的踩坑经历。


公众号:蓝海资料掘金营,微信deep3321