Hadoop YARN:ApplicationMaster向ResourceManager註冊AM源碼調試

#0. 先看一下測試demo的運行流程


a.創建一個YARN客戶端YarnClient,

並與ResourceManager建立連接

b.通過YARN客戶端創建一個應用並獲取到應用提交上下文對象、設置相關的屬性

  • 特別是需要設置setAMContainerSpec,

          防止後面getTokensConf時報空指針異常;

  • 還需要設置setUnmanagedAM,不需要RM來管理AM(分配並啓動Container),置爲true之後就不再需要設置請求的資源大小了(UAM主要用來做測試)。

c.通過YARN客戶端提交應用

d.獲取並監控應用的狀態ApplicationReport

e.判斷應用狀態,如果爲ACCEPTED(已接受),則繼續監控應用嘗試的啓動狀態,並獲取到應用嘗試ID

f.跟據應用嘗試ID獲取到通信令牌Token

g.拿着Token去註冊ApplicationMaster

h.最後輸出一下響應信息

RegisterApplicationMasterResponse

測試代碼片段:


@Test
public void testAMRMClientAsync() throws Exception {
    YarnConfiguration yarnConfig = new YarnConfiguration();
    YarnClient yarnClient = YarnClient.createYarnClient();
    yarnClient.init(yarnConfig);
    // a.創建一個YARN客戶端YarnClient,並與ResourceManager建立連接
    yarnClient.start();

    // 應用提交上下文
    ApplicationSubmissionContext appContext = yarnClient.createApplication().getApplicationSubmissionContext();
    ApplicationId appId = appContext.getApplicationId();
    // 設置應用名稱
    appContext.setApplicationName("zlxiaoxiang_test");
    // 爲ApplicationMaster設置優先級
    Priority pri = Records.newRecord(Priority.class);
    pri.setPriority(1);
    appContext.setPriority(pri);
    // 設置調度隊列名稱 默認default
    appContext.setQueue("default");

    // 爲AM設置Container啓動的上下文
    ContainerLaunchContext amContainer = Records.newRecord(ContainerLaunchContext.class);
    // 防止tokenConf報空指針異常 ByteBuffer tokenConf = submissionContext.getAMContainerSpec().getTokensConf();
    appContext.setAMContainerSpec(amContainer);
    // 不由RM管理,此處設置爲true;RM不會爲AM分配Container並啓動它;
    appContext.setUnmanagedAM(true);
    // 設置要請求的資源大小
//        appContext.setResource(Resource.newInstance(512, 1));

    // c.通過YARN客戶端提交應用
    yarnClient.submitApplication(appContext);
    // d.獲取並監控應用的狀態ApplicationReport
    ApplicationReport appReport = monitorApplication(yarnClient, appId, EnumSet.of(YarnApplicationState.ACCEPTED,
            YarnApplicationState.KILLED, YarnApplicationState.FAILED,
            YarnApplicationState.FINISHED));

    // e.判斷應用狀態,如果爲ACCEPTED(已接受),則繼續監控應用嘗試的啓動狀態,並獲取到應用嘗試ID
    if (appReport.getYarnApplicationState() == YarnApplicationState.ACCEPTED) {
        // 監控應用狀態
        ApplicationAttemptReport attemptReport = monitorCurrentAppAttempt(yarnClient, appId, YarnApplicationAttemptState.LAUNCHED);
        // 應用嘗試ID、用於啓動ApplicationMaster
        ApplicationAttemptId attemptId = attemptReport.getApplicationAttemptId();

        // f.跟據應用嘗試ID獲取到通信令牌Token
        Token<AMRMTokenIdentifier> token = yarnClient.getAMRMToken(attemptId.getApplicationId());

        UserGroupInformation userGroupInformation = UserGroupInformation.getCurrentUser();

        userGroupInformation.addToken(token);

        // g.拿着Token去註冊AM,否則跳轉不到RM服務端
        userGroupInformation.doAs((PrivilegedExceptionAction<Void>) () -> {
            // 創建一個AM-RM異步客戶端
            AMRMClientAsync<AMRMClient.ContainerRequest> resourceManagerClient = AMRMClientAsync.createAMRMClientAsync(
                    5000, new TestCallbackHandler());

            resourceManagerClient.init(yarnConfig);
            // 與RM建立連接
            resourceManagerClient.start();

            // 調用registerApplicationMaster
            final RegisterApplicationMasterResponse registerApplicationMasterResponse =
                    resourceManagerClient.registerApplicationMaster("localhost", 10088, "https://blog.icocoro.me/");

            LOG.info("registerApplicationMasterResponse: " + registerApplicationMasterResponse);

            return null;
        });

    }

    yarnClient.stop();

}

整個DEBUG過程:

a.在idea中DEBUG模式啓動ResourceManager,

在重點關注的位置打上斷點,也可以邊調試邊打斷點

 

b.在idea中DEBUG模式運行testAMRMClientAsync,

從主要關注的位置開始一步一步往下走

 

#1. DEBUG模式運行ResourceManager

 

#2. 瀏覽器訪問默認的8088端口

 

#3. 調試開始,跳到提交應用的斷點位置

 

#4. 會調用到RM端的ClientRMService,此處是可能發生NPE的位置

客戶端設置了相關屬性即可避免

 

#5. 調用到RM端的RMAppManager,進行應用註冊

 

#6. 應用註冊結束,返回到測試客戶端

判斷應用當前的狀態

 

#7. 觀察YARN的WEB界面

已經有一個應用了,狀態是ACCEPTED

 

#8. 需要取得通信Token

可以看到Token的屬性:


private byte[] identifier;
private byte[] password;
private Text kind;
private Text service;
private TokenRenewer renewer;

 

#9. 準備調用AMRMClientAsync的

registerApplicationMaster方法

 

#10. 進入AMRMClientAsyncImpl

 

#11. 進入AMRMClientImpl

這裏用到rmClient

是一個ApplicationMasterProtocolPBClientImpl對象

 

 

#12. 進入

ApplicationMasterProtocolPBClientImpl

這裏用到proxy

是一個ApplicationMasterProtocolPBServiceImpl對象

 

 

#13. 進入

ApplicationMasterProtocolPBServiceImpl

這裏用到real

是一個ApplicationMasterService對象

 


 

#14. 進入ApplicationMasterService

這裏用到amsProcessingChain

是一個AMSProcessingChain對象

實現了ApplicationMasterServiceProcessor接口

public interface ApplicationMasterServiceProcessor {

  /**
   * Initialize with and ApplicationMasterService Context as well as the
   * next processor in the chain.
   * @param amsContext AMSContext.
   * @param nextProcessor next ApplicationMasterServiceProcessor
   */
  void init(ApplicationMasterServiceContext amsContext,
      ApplicationMasterServiceProcessor nextProcessor);

  /**
   * Register AM attempt.
   * @param applicationAttemptId applicationAttemptId.
   * @param request Register Request.
   * @param response Register Response.
   * @throws IOException IOException.
   * @throws YarnException in critical situation where invalid
   *         profiles/resources are added.
   */
  void registerApplicationMaster(ApplicationAttemptId applicationAttemptId,
      RegisterApplicationMasterRequest request,
      RegisterApplicationMasterResponse response)
      throws IOException, YarnException;

  /**
   * Allocate call.
   * @param appAttemptId appAttemptId.
   * @param request Allocate Request.
   * @param response Allocate Response.
   * @throws YarnException YarnException.
   */
  void allocate(ApplicationAttemptId appAttemptId,
      AllocateRequest request, AllocateResponse response) throws YarnException;

  /**
   * Finish AM.
   * @param applicationAttemptId applicationAttemptId.
   * @param request Finish AM Request.
   * @param response Finish AM Response.
   */
  void finishApplicationMaster(
      ApplicationAttemptId applicationAttemptId,
      FinishApplicationMasterRequest request,
      FinishApplicationMasterResponse response);
}

 

#15. 進AMSProcessingChain

這裏的head是個DisabledPlacementProcessor

當然也是ApplicationMasterServiceProcessor

 

 

#16. 最終會進DefaultAMSProcessor

DefaultAMSProcessor是AMSProcessingChain裏最後一個processor

這裏面會有一塊核心代碼:

getRmContext().getDispatcher().getEventHandler()
        .handle(
            new RMAppAttemptRegistrationEvent(applicationAttemptId, request
                .getHost(), request.getRpcPort(), request.getTrackingUrl()));

 

#17. 返回到AMRMClientAsyncImpl的註冊方法裏面

 

#18. 查看YARN的WEB UI

顯示應用的狀態爲RUNNING。

Running Containers爲0,也就是並沒有分配實際的Container在運行。

 

返回的註冊響應信息:

INFO  test.MyTestAMRMClientAsync (MyTestAMRMClientAsync.java:lambda$testAMRMClientAsync$0(97)) - registerApplicationMasterResponse: maximumCapability { memory: 8192 virtual_cores: 4 resource_value_map { key: "memory-mb" value: 8192 units: "Mi" type: COUNTABLE } resource_value_map { key: "vcores" value: 4 units: "" type: COUNTABLE } } queue: "default" scheduler_resource_types: MEMORY resource_profiles { } resource_types { name: "memory-mb" units: "Mi" type: COUNTABLE } resource_types { name: "vcores" units: "" type: COUNTABLE }
Disconnected from the target VM, address: '127.0.0.1:55513', transport: 'socket'

以上就是AM註冊自己的整體宏觀過程。

【END】

 

往期推薦:

Apache Hadoop YARN:Client<-->ResourceManager源碼解析

Apache Hadoop YARN:Client<-->ResourceManager源碼DEBUG

Hadoop YARN:ApplicationMaster與ResourceManager交互源碼解析

Hive企業級調優

HiveQL查詢連續三天有銷售記錄的店鋪

HiveQL實戰螞蟻森林低碳用戶排名分析:解法一

HiveQL實戰螞蟻森林低碳用戶排名分析:解法二

HiveQL實戰螞蟻森林植物申領統計分析

Hive-函數

Hive-查詢

Hive-DML(Data Manipulation Language)數據操作語言

Hive-DDL(Data Definition Language)數據定義

Hive優化(整理版)

Spark Core之Shuffle解析

數據倉庫開發規範

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章