第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 调度流程
我简单描述一下作业提交的完整流程:
- 客户端提交作业到ResourceManager
- RM在某个NodeManager上启动一个Container,运行ApplicationMaster
- AM向RM注册,并申请更多资源
- RM分配资源,AM在对应的NodeManager上启动任务Container
- 任务执行过程中,AM持续监控进度
- 任务完成后,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 调度流程
- 过滤阶段:排除不满足条件的Node(比如资源不足、端口冲突)。
- 打分阶段:对剩余Node进行评分,选出最优的。
- 绑定阶段:将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