Hadoop 1.x 时使用 JobTracker 对 MapReduce 任务进行任务调度,但这样导致一个结果,部署了 JobTracker 的节点只能够支持 MapReduce 类型的任务,当需要运行其他类型的任务时,我们只能重新搭建一个计算集群去运行。
在大数据开发的过程中,我们会使用到不同的计算框架,如 Hadoop, Spark, Flink, Storm... 如果对于每一种计算框架,我们都需要去单独的部署计算集群,这将是极大的资源浪费。
为了让各种类型的任务能够运行在同一个计算集群上,Hadoop 2.x 引入了一个全新的 Module -- Yarn ( Yet Another Resource Manager )。
Yarn 对任务分配同具体计算逻辑进行了解耦,对整个分布式任务做了两种形式的抽象:
- 资源抽象 -- NodeManager 将自身节点的内存和 CPU 核数信息上报给 ResourceManager 进行统一管理。当需要运行任务时,在 NodeManager 中启动拥有一定内存和 CPU 核数的 Container 进行进行任务执行。
- 任务抽象 -- Yarn 将需要运行的分布式任务抽象为 Application,放弃对任务执行命令的介入,由 Client 自定义 的AppMaster 进行资源申请和任务执行,从而将自身同任务本身解耦,只负责资源调度,和具体任务类型无关。
通过资源抽象,简化了 Yarn 管理集群资源的复杂度,将任务启动的调度策略简化成对各个 NodeManager 中的资源分配问题。简单来说就是,Yarn 负责为 Application 提供所需要的内存和 CPU 资源,并启动独立进程运行分布式任务,但并不关心分布式任务的具体操作。
通过任务抽象,扩展了 Yarn 的使用场景,将 Yarn 从单一的 MapReduce 任务调度系统扩展成一个通用的任务调度程序。不同的使用场景下,只需要实现自己特定的 YarnApplication 即可运行分布式任务。常用的一些大数据处理程序例如 Spark , Flink 等都支持通过 Yarn 上进行任务调度。
Yarn 的组件构成
Yarn 由三个组件构成:
- ResourceManager(RM) 负责管理和调度整个 Yarn 集群的预算资源,同时使用和 Hdfs 中 NameNode 相同的代码,基于 ZooKeeper 实现 ActiveStandby 的高可用逻辑。
- NodeManager(NM) 部署在各个任务执行节点上,负责节点生命状态的上报以及具体任务的运行。
- YarnClient(Client) 用户创建 YarnApplication 后,通过 YarnClient 提交给 RM 进行任务调度执行。
下文中三个组件的名称将会简写为 RM, NM 和 Client。
Yarn 作业类型
之前有说过 Yarn 为了提高整个框架的通用性,将需要执行的分布式任务抽象为 Application,同时引入 AppMaster 机制令 Yarn 同任务操作本身解耦。
Yarn 中的作业类型分为两类:
- 普通任务类型: 分布式任务的具体执行者,当从 RM 中申请到任务资源后,会在 NM 单独启动的 Container 中运行,负责执行指定的计算任务。
- AppMaster: 分布式任务的协调者,每个 YarnApplication 提交到 RM 后,都会唯一的启动一个 AppMaster,负责具体组织整个分布式任务,从 RM 中申请任务资源,并协调其他任务正常运行。
AppMaster 中的协调代码是由提交的 YarnApplication 中定义的,当分布式任务开始执行时,通过不同的协调代码可以实现不同的任务类型,实现分布式任务的多样化。同时 AppMaster 和普通任务类型一样,运行在 NM 节点中的 Container 中,它的协调过程是在 NM 节点上产生的,实现了不同 Application 资源的物理隔离,使得在逻辑上单个 Application 不会对其他 Application 构成影响。
总结
Yarn 同上一代的 JobTracker 相比,主要特点是将计算逻辑同资源分配解耦。自身只关注对任务所需要的资源进行分配,具体的计算逻辑和资源请求计算交给 Application 自身完成。
剥离出计算逻辑后,Yarn 的职责更加单一,其他的计算框架也可以通过实现 YarnApplication 完成自己的分布式计算任务,使得所有类型的任务都可以在同一个计算集群中进行,提升对整个计算集群资源的利用效率。