YarnRunner類分析

bgpydpyr發表於2016-03-03

之前一篇文章分析了Yarn通過ServiceLoader建立ClientProtocol的實現類為YarnRunner,實際上閱讀原始碼可以知道YarnRunner的建立時機為作業提交連線叢集之時,Cluster初始化時建立的。知道了yarn框架建立了YarnRunner,那麼YarnRunner到底是幹什麼的呢? 看一下YarnRunner的類圖主要部分。 enter image description here

YarnRunner實現了介面ClientProtocol。官方文件對於ClientProtocol的解釋是 Protocol that a JobClient and the central JobTracker use to communicate. The JobClient can use these methods to submit a Job for execution, and learn about the current system status.(作業客戶端和中央排程器用來通訊的協議,作業客戶端可以使用這個類的一些方法來提交一個作業並執行,也可以獲知當前系統的狀態。)

那麼Yarn是內部是如何實現client到中央排程器也就是ResourceManager的通訊的呢?看YarnRunner的構造方法:

public YARNRunner(Configuration conf) {

   this(conf, new ResourceMgrDelegate(new YarnConfiguration(conf)));
  }

YarnRunner有一個ResourceMgrDelegate型別的resMgrDelegate的私有成員變臉。ResourceMgrDelegate類是ResourceManager通訊的ApplicationClientProtocol的一個委派,在構造YarnRunner時會首先根據配置資訊初始化resMgrDelegate。如下是與ResourceMgrDelegate相關的類圖。 enter image description here 可以看到ResourceMgrDelegate類實現了Service介面 Service類定義了列舉型別 enum STATE

/** Constructed but not initialized */
    NOTINITED(0, "NOTINITED"),

    /** Initialized but not started or stopped */
    INITED(1, "INITED"),

    /** started and not stopped */
    STARTED(2, "STARTED"),

    /** stopped. No further state transitions are permitted */
    STOPPED(3, "STOPPED");

和init(),start(),stop(),close()等方法,AbstractService是一個實現了Service的抽象類它實現了Service中的方法並新增了一些serviceStart()和serviceStop()的抽象方法,在start()的實現邏輯中呼叫了serviceStart(),這是一種模板設計模式,我們只要繼承AbstractService並實現回撥方法serviceStart()方法在裡面寫相應的啟動邏輯並呼叫start()方法就可以啟動對於的服務。Service中的列舉STATE定義了服務的四種狀態,這些狀態不都是可以相互轉化的,通過ServiceStateModelstatemap二維陣列來約束他們之間的轉化關係:

  private static final boolean[][] statemap =
    {
      //                uninited inited started stopped
      /* uninited  */    {false, true,  false,  true},
      /* inited    */    {false, true,  true,   true},
      /* started   */    {false, false, true,   true},
      /* stopped   */    {false, false, false,  true},
    };

知道了這些後再看ResourceMgrDelegate的建構函式:

public ResourceMgrDelegate(YarnConfiguration conf) {
    super(ResourceMgrDelegate.class.getName());
    this.conf = conf;
    //建立一個YarnClientImpl
    this.client = **YarnClient.createYarnClient();**
    init(conf);
    start();
  }

很顯然它在構造時呼叫了 YarnClient.createYarnClient()建立了一個YarnClient的實現類YarnClientImpl,呼叫init()、start()方法內部會做一些狀態轉換,同時start()方法內部會呼叫serviceStart()方法,看看它的serviceStart()方法。

protected void serviceStart() throws Exception {
    client.start();
    super.serviceStart();
  }

呼叫了clientstart(),也就是YarnClientImplstart(),start()方法又會在內部掉用YarnClientImplserviceStart()方法,我們來看一看YarnClientImplserviceStart()方法長啥樣:

@Override
  protected void serviceStart() throws Exception {
    try {
      rmClient = ClientRMProxy.createRMProxy(getConfig(),
          ApplicationClientProtocol.class);
      if (historyServiceEnabled) {
        historyClient.start();
      }
      if (timelineServiceEnabled) {
        timelineClient.start();
      }
    } catch (IOException e) {
      throw new YarnRuntimeException(e);
    }
    super.serviceStart();
  }

YarnClientImpl我們關注這樣一行程式碼 rmClient = ClientRMProxy.createRMProxy(getConfig(), ApplicationClientProtocol.class); 建立rmClient便是建立YarnRunner的一個很重要的目的,rmClient是一個ApplicationClientProtocol的實現類是負責client與叢集ResourceManager的通訊的RPC協議。在以後的分析中我們將會分析rmClient的具體建立過程。

相關文章