深入理解 Hadoop (五)YARN核心工作机制浅析

概述

YARN 的核心设计理念是 服务化(Service)事件驱动(Event + EventHandler)。服务化 和 事件驱动 软件设计思想的引入,使得 YARN 具有低耦合、高内聚的特点,各个模块只需完成各自功能,而模块之间则采用事件联系起来,系统设计简单且维护方便。这种编程方式具有异步、并发等特点,更加高效,更适合大型分布式系统。

YARN Service 服务

对于生命周期较长的对象,YARN 采用了基于服务的对象管理模型对其进行管理,该模型主要有以下几个特点:

将每个被服务化的对象分为 4 个状态:NOTINITED(被创建)、INITED(已初始化)、STARTED(已启动)、STOPPED(已停止)

任何服务状态变化都可以触发另外一些动作。

可通过组合的方式对任意服务进行组合,以便进行统一管理。

复制代码
public class ResourceManager extends CompositeService implements Recoverable, ResourceManagerMXBean {
}

public class NodeManager extends CompositeService implements EventHandler<NodeManagerEvent>, NodeManagerMXBean {
}

public class CompositeService extends AbstractService {
    // 服务集合
    private final List<Service> serviceList = new ArrayList<Service>();
}

public abstract class AbstractService implements Service {
}

ResourceManager 继承关系图

service 定义

Service 的主要逻辑位于 serviceInt()、serviceStart()、serviceStop() 等方法中。

Service 用到了组合模式 + 装饰者模式

复制代码
public interface Service extends Closeable {
    public enum STATE {
        NOTINITED(0, "NOTINITED"),
        INITED(1, "INITED"),
        STARTED(2, "STARTED"),
        STOPPED(3, "STOPPED");
    }
    // 服务初始化
    void init(Configuration config);
    // 服务启动
    void start();
    // 服务停止
    void stop();
    // 服务关闭
    void close() throws IOException;
}

ResourceManager 的内部构成

NodeManager 的内部构成

YARN AsyncDispatcher 事件驱动机制详解

其他的组件提交事件到 这个 AsyncDispatcher,内部通过一个队列来缓冲,然后 AsyncDispatcher 的内部还有一个消费线程,获取队列中的事件,然后做分发到 事件 和 事件处理器 的注册表中,去根据事件找到事件处理器,调用 事件处理器 的 handle 方法来完成事件处理。
异步 :这个异步组件的内部,必然包含一个 队列 和一个 消费线程。
AsyncDispatcher :异步事件驱动模型的中央事件调度器,所以它的内部,注册了很多的<Event + EventHandler> 事件处理二元组。

YARN 采用了基于事件驱动的异步通信模型,该模型能够大大增强并发性,从而提高系统整体性能。为了构建该模型,YARN 将各种处理逻辑抽象成事件和对应事件调度器,并将每类事件的处理过程分割成多个步骤,用有限状态机表示。

AsycDispatcher 是 YARN 的中央异步调度器/ 全局事件分发器。在 ResourceManager 中,几乎所有的事件都通过 AsyncDispatcher 进行事件的派发。当一个组件提交一个 事件给 AsyncDispatcher 的时候,AsyncDispatcher 负责给这个事件找到之前注册的 EventHandler 来完成响应的处理。某些特别的 EventHandler 可能是一个 StateMachine。

整个处理过程大致为:处理请求会作为事件进入系统,由中央异步调度器(AsyncDispatcher)负责传递给相应事件调度器(EventHandler)。该事件调度器可能将该事件转发给另外一个事件调度器,也可能交给一个带有有限状态机的事件处理器,其处理结果也以事件的形式输出给中央异步调度器。而新的事件会再次被中央异步调度器转发给下一个事件调度器,直至处理完成(达到终止条件)。

在 YARN 中,所有核心服务实际上都是一个中央异步调度器,包括 ResourceManager、NodeManager、MRAppMaster 等,它们维护了事先注册的事件与事件处理器,并根据接收的事件类型驱动服务的运行。以 MRAppMaster 为例,它内部包含一个中央异步调度器 AsyncDispatcher,并注册了 TaskAttemptEvent / TaskAttemptImpl、TaskEvent / TaskImpl、JobEvent / JobImpl 等一系列事件/事件处理器,由中央异步调度器统一管理和调度。

在 ResourceManager 或者 NodeManager 等组件中,都有一个 AsyncDispatcher 中央异步事件调度器。在初始化的时候,会将创建的 EventHandler 和对应的事件类型,注册到 AsyncDispatcher 中来,如果 AsyncDispatcher 接收到一个事件,由 GenericEventHandler 完成 eventQueue 的容量维护,并且将事件加入到 eventQueue 中,负责消费 eventQueue 的 eventHandlingThread 则从 eventDispatchers 获取注册的事件对应的 EventHandler 来完成处理。所以:这样子看,AsyncDispatcher 就是一个中央事件调度分发器。

YARN StateMachine 有限状态机

EventHandler 可以理解为简化版的策略模式。

复制代码
class XXX implemnts EventHandler<>{
    private StateMachine machine;
}
// 1、XXX 是一个 EventHandler。
// 2、XXX 是一个有限状态机,这个 XXX 的状态变化比较复杂,通过一个有限状态机来维护。
// 3、XXX 称之状态机实体对象,维护了当前的状态信息。

在 YARN 中,每种状态转换(doTransition 方法去执行状态转换,addTransition 注册状态转换)由一个四元组表示,分别是转换前状态(preState)、转换后状态(postState)、事件(event)和回调函数/转换器(hook = Transition)。

连起来解释: 此时是 preState,接收到 event 之后,状态机转换表中获取到对应的 Transition 执行转换,得到一个新状态 postState。YARN 定义了三种状态转换方式,具体如下:

  • 一个初始状态、一个最终状态、一种事件:经过处理之后,无论如何,进入到一个唯一状态。
  • 一个初始状态、多个最终状态、一种事件:不同的逻辑处理结果,可能导致进入不同的状态。
  • 一个初始状态、一个最终状态、多种事件:多个不用的事件,可能触发到多个不同状态的转换。

YARN 有限状态机设计理念

  • 首先构建一个 StateMachineFactory 实例,然后往里面注册响应的状态转换四元组。
  • 调用 StateMachineFactory 的 make() 来构造一个 StateMachine 实例。
  • StateMachineFactory 内部维护了一个 stateMachineTable。
  • 当正常运行过程中,如果接收到一个事件,则根据 此时的状态 和 事件找到对应的转换器 Transition,调用 Transition 的 doTransition 方法来执行转换,得到最终状态。

YARN 中实现了多个状态机对象,包括:

ResourceManager 中的 RMAppImpl、RMAppAttemptImpl、RMContainerImpl 和 RMNodeImpl 等。

NodeManager 中的 ApplicationImpl、ContainerImpl 和 LocalizedResource 等。

MRAppMaster 中的 JobImpl、TaskImpl 和 TaskAttemptImpl 等。

状态机可视化工具

为了便于用户查看这些状态机的状态变化以及相关事件,YARN 提供了一个状态机可视化工具,具体操作步骤如下。

步骤1 将状态机转化为 graphviz(.gv) 格式的文件,在源代码根目录下执行编译命令如下:

复制代码
mvn compile -Pvisualize

步骤2 使用可视化包 graphviz 中的相关命令生成状态机图,Shell 命令具体如下:

复制代码
dot -Tpng ResourceManager.gv > ResourceManager.png
dot -Tpng NodeManager.gv > NodeManager.png
dot -Tpng MapReduce.gv > MapReduce.png

如果尚未安装 graphviz 包,操作该步骤之前先要安装该包,centos 安装命令如下:

复制代码
sudo yum install graphviz

源码中如何查看事件对象处理方式

方式一 : 搜枚举类实例,例如:RMNodeEventType.STARTED,搜到的结果是状态机,一般位于 adTransition 方法中。
方式二: 搜枚举类实例,例如:case STARTED 或 RMNodeEventType.class,搜到的结果是事件处理器,一般位于 register 方法中。

相关推荐
咸鱼求放生3 小时前
es在Linux安装
大数据·elasticsearch·搜索引擎
记得开心一点嘛3 小时前
使用MinIO搭建自己的分布式文件存储
分布式·spring cloud·minio
纪元A梦5 小时前
分布式拜占庭容错算法——PBFT算法深度解析
java·分布式·算法
人大博士的交易之路5 小时前
今日行情明日机会——20250606
大数据·数学建模·数据挖掘·数据分析·涨停回马枪
神奇侠20246 小时前
Hive SQL常见操作
hive·hadoop·sql
Leo.yuan8 小时前
数据库同步是什么意思?数据库架构有哪些?
大数据·数据库·oracle·数据分析·数据库架构
SelectDB技术团队9 小时前
从 ClickHouse、Druid、Kylin 到 Doris:网易云音乐 PB 级实时分析平台降本增效
大数据·数据仓库·clickhouse·kylin·实时分析
Web极客码10 小时前
在WordPress上添加隐私政策页面
大数据·人工智能·wordpress
TCChzp10 小时前
Kafka入门-消费者
分布式·kafka
Apache Flink10 小时前
Flink在B站的大规模云原生实践
大数据·云原生·flink