YARN的AsyncDispatcher原理

博客原文:hackershell

YARN采用了基于事件驱动的并发模型,该模型能极大的提高应用程序并发性,在RM中,几乎所有的事件都通过AsyncDispatcher进行事件的派发.

其基本架构图如下:

AsyncDispatcher

从基本的架构图可以简单的看出,该模型还需要几个基本的要素,那就是事件(Event),事件类型(EventType)和处理事件对应的处理器(Handler).

在HADOOP中,事件被定义如下:

public interface Event<TYPE extends Enum<TYPE>> {

  TYPE getType();
  long getTimestamp();
  String toString();
}

事件类型(EventType)则是简单的枚举类

主要功能定义事件有哪几种类型:

public enum NodesListManagerEventType {
  NODE_USABLE,
  NODE_UNUSABLE
}

处理事件的接口

主要功能处理相应的事件

public interface EventHandler<T extends Event> {
  void handle(T event);
}

Dispatcher通过不同的事件类型(EventType)找到相应的handler对事件(event)进行处理.

对于AsyncDispatcher来说,它实现了Dispatcher接口:

public interface Dispatcher {
  EventHandler getEventHandler();
  void register(Class<? extends Enum> eventType, EventHandler handler);
}

其中有两个基本的方法,registergetEventHandler

register在AsyncDispatcher使用之前就需要先注册eventType和对应的EventHandler,而getEventHandler方法主要则是把事件(event)放入eventQueue中.

接下来在ResourceManager举个简单的例子:

在RM初始化自身基本服务的时候,会把相应的事件类型(EventType)和事件处理器(EventHandler),先注册在AsyncDispatcher上,以便于派发器在事件(event)到来时做出相应的处理.

RM的部分代码:

// Register event handler for RmNodes
this.rmDispatcher.register(RMNodeEventType.class,
    new NodeEventDispatcher(this.rmContext)); 

其实注册也就是把相应的类型和处理器放到一个HashMap

因为是资源管理方面的服务,所以我们进入ResourceTrackerService类中,找到nodesListManager这个实例,通过代码可以知道nodesListManager是用来管理节点是否可用,并作出相应的处理

// 2. Check if it's a valid (i.e. not excluded) node
    if (!this.nodesListManager.isValidNode(rmNode.getHostName())) {
      String message =
          "Disallowed NodeManager nodeId: " + nodeId + " hostname: "
              + rmNode.getNodeAddress();
      LOG.info(message);
      shutDown.setDiagnosticsMessage(message);
      this.rmContext.getDispatcher().getEventHandler().handle(
          new RMNodeEvent(nodeId, RMNodeEventType.DECOMMISSION));
      return shutDown;
    }

从代码可以看出,如果节点是非法的,则从Dispatcher获取Handler,并构造一个RMNodeEventType.DECOMMISSION类型的事件,这个RMNodeEvent将会被放到eventQueue中

class GenericEventHandler implements EventHandler<Event> {
    public void handle(Event event) {
      try {
        eventQueue.put(event);
      } catch (InterruptedException e) {

      }
    };
  }

最后由dispatch进行通过传入的RMNodeEventType找到相应的NodeEventDispatcher(即EventHandler),并调用handle进行处理.

总结:
通过了解AsyncDispatcher可以提升自己理解Yarn的工作流程,加深对Yarn的设计实现的了解.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Resource Page Description 在以前的文章中,我曾多次强调应用程序中异步化的重要性。尤其对于IO密集型操作,异步执行对于应用程序的响应能力和伸缩性有非常关键的影响。正确使用异步编程能够使用尽可能少的线程来执行大量的IO密集型操作。可惜的是,即时异步编程有避免线程阻塞等诸多好处,但是这种编程方式至今没有被大量采用。其原因有很多,其中最主要的一点可能就是异步模型在编程较为困难,导致许多开发人员不愿意去做。 异步,则意味着一个任务至少要被拆分为“二段式”的调用方式:一个方法用于发起异步请求,另一个方法用于异步任务完成后的回调。与传统方法调用方式相比,异步调用时的中间数据不能存放在线程栈上,方法之间的也不能简单地通过参数传递的方式来共享数据。此外,传统方法调用中的try…catch…finally,using等关键字都无法跨越方法边界,因此异步编程在处理异常,保护资源等方面也需要花更大的精力才行。如果一不小心,轻则造成资源泄露,重则使整个应用程序崩溃。 因此,无论是微软官方还是社区中都出现了一些简化异步编程方式的组件,例如微软并行与协调运行时和Wintellect's .NET Power Threading Library中的AsyncEnumerator。同时,我基于AsyncEnumerator构建了一个AsyncTaskDispatcher组件,使多个有依赖关系的异步操作之间的协作调用得以大大简化。 以上是引用,自己做了个更简单的demo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值