Hadoop yarn源码分析(二) NodeManager源码分析 2021SC@SDUSC

2021SC@SDUSC

一、NM简介

Yarn的三大核心组件为ResourceManager(RM)ApplicationMaster(AM)NodeMananger(NM)
NodeManager是执行在单个节点上的代理,负责管理Hadoop集群中的单个计算节点。主要有与ResourceManager保持通信,监控管理Container的生命周期和使用情况,管理日志和不同应用程序用到的附属服务等功能。

二、内部架构

NM内部架构图
1.NodeStatusUpdater:这个组件是NM与RM通信的唯一通道,包括NM注册之后向RM的注册汇报资源,以及周期性的汇报节点信息和Container的运行状态,同时RM会返回给待清理的Container列表,待清理的应用程序,诊断信息等。
2.ContainerManager: 该组件是NM最核心的组件之一,由许多组件构成,各组件共同管理运行在该节点上的所有Container。部分组件的功能如下:
(1)RPCServer :实现了ContainerManagementProtocol协议,是AM和NM通信的唯一通道。
ContainerManager从各个ApplicationMaster上接受RPC请求以启动新的Container或者停止正在执行的Contaier。
(2)ContainerEventDispatcher:Container的事件调度器,负责将ContainerEvent类型的事件调度给对应Container的状态机ContainerImpl。
(3)ApplicationEventDispatcher: Application的事件调度器,负责将ApplicationEvent类型的事件调度给Application的状态机ApplicationImpl。
3.ContainerExecutor: 它可与底层的操作系统交互,安全存放Container的文件和目录,进而安全的启动和清理Container。
4.NodeHealthCheckerService: 周期性运行一个向磁盘写文件的脚本,检测节点的健康状态,并汇报给RM。
5.DeletionService: NodeManager删除文件组件。
6.Security: 安全模块。
7.WebServer: 通过Web界面向用户展示该节点上所有应用程序运行状态、 Container列表、 节点健康状况和Container产生的日志等。

三、基本职能

NM通过两个RPC协议与AM进行交互,从AM上接收Container相关命令(启动、停止Container)并执行,向RM汇报Container的运行状态和节点健康状态,并领取相关Container的命令执行。两个RPC协议分别是ResourceTrackerProtocol协议,ContainerManagementProtocol协议。

3.1 ResourceTrackerProtocol协议

在该协议中,RM相当于RPC Server,NM相当于RPC Client。NM通过该RPC协议向RM注册汇报节点的健康状态以及Container的运行状态,并接收RM命令,如初始化、清理Container等。

协议具体代码:

syntax = "proto2";
option java_package = "org.apache.hadoop.yarn.proto";
option java_outer_classname = "ResourceTracker";
option java_generic_services = true;
option java_generate_equals_and_hash = true;
package hadoop.yarn;

import "yarn_server_common_service_protos.proto";

service ResourceTrackerService {
  rpc registerNodeManager(RegisterNodeManagerRequestProto) returns (RegisterNodeManagerResponseProto);
  rpc nodeHeartbeat(NodeHeartbeatRequestProto) returns (NodeHeartbeatResponseProto);
  rpc unRegisterNodeManager(UnRegisterNodeManagerRequestProto) returns (UnRegisterNodeManagerResponseProto);
}

3.1.1 注册:registerNodeManager

注册,需要将自己的http端口号(httpPort),RPC端口号(nodeId)以及总资源量(totalResource)传送给RM,在RegisterNodeManagerRequest将这些必要信息封装。

RegisterNodeManagerRequest封装:

//org.apache.hadoop.yarn.server.api.protocolrecords.RegisterNodeManagerRequest.java
public static RegisterNodeManagerRequest newInstance(NodeId nodeId,
      int httpPort, Resource resource, String nodeManagerVersionId,
      List<NMContainerStatus> containerStatuses,
      List<ApplicationId> runningApplications) {
    return newInstance(nodeId, httpPort, resource, nodeManagerVersionId,
        containerStatuses, runningApplications, null);
  }

3.1.2 心跳:nodeHeartbeat

NM启动后,通过RPC协议向RM注册。汇报节点健康状况和Container执行状态,并领取新的命令,包含又一次初始化、清理Container资源等。

//org.apache.hadoop.yarn.server.resourcemanager.ResourceTrackerService.java
protected void serviceInit(Configuration conf) throws Exception {

    RackResolver.init(conf);
    
    if (YarnConfiguration.areNodeLabelsEnabled(conf)) {
      isDistributedNodeLabelsConf =
          YarnConfiguration.isDistributedNodeLabelConfiguration(conf);
      isDelegatedCentralizedNodeLabelsConf =
          YarnConfiguration.isDelegatedCentralizedNodeLabelConfiguration(conf);
    }
    updateHeartBeatConfiguration(conf);
    loadDynamicResourceConfiguration(conf);
    decommissioningWatcher.init(conf);
    super.serviceInit(conf);
  }

3.2 ContainerManagementProtocol协议

应用程序的AM通过RPC协议向NM发起针对Container的相关操作,包含启动Container、杀死Container、获取Container运行状态。AM能将Container的相关信息通过RPC的方式第一时间传送给NM。
主要提供了三个RPC函数:
1.startContainer:有一个參数封装了Container启动所须要的本地资源、环境变量、运行命令、Token等信息。
2.stopContainer:AM通过该RPC要求NodeManager停止(杀死)一个Container。该函数有一个StopContanerRequest类型的參数,用于指定待杀死的Container ID.
3.getContainerStatus:AM通过该RPC获取一个Container的执行状态。该函数參数类型为GetContaineStatusRequest,封装了目标Container 的ID。

四、NM初始化

NodeManager的服务初始化都是由serviceInit方法来处理的,里面详细的描述了NM服务用到的子服务。包含node资源监控服务、容器管理服务、web通讯服务、安全服务等。

//org.apache.hadoop.yarn.server.nodemanager.Nodemanager.java
  protected void serviceInit(Configuration conf) throws Exception {
  ...
    //创建创建 ContainerExecutor
    ContainerExecutor exec = createContainerExecutor(conf);
    try {
    //初始化
      exec.init(context);
    } catch (IOException e) {
      throw new YarnRuntimeException("Failed to initialize container executor", e);
    }
    DeletionService del = createDeletionService(exec);
    addService(del);

    // NodeManager level dispatcher
    this.dispatcher = createNMDispatcher();

    //健康检测服务
    this.nodeHealthChecker = new NodeHealthCheckerService(dirsHandler);
    addService(nodeHealthChecker);

    ((NMContext)context).setContainerExecutor(exec);
    ((NMContext)context).setDeletionService(del);

    nodeStatusUpdater =
        createNodeStatusUpdater(context, dispatcher, nodeHealthChecker);

    nodeLabelsProvider = createNodeLabelsProvider(conf);
    if (nodeLabelsProvider != null) {
      addIfService(nodeLabelsProvider);
      nodeStatusUpdater.setNodeLabelsProvider(nodeLabelsProvider);
    }

    //node属性
    nodeAttributesProvider = createNodeAttributesProvider(conf);
    if (nodeAttributesProvider != null) {
      addIfService(nodeAttributesProvider);
      nodeStatusUpdater.setNodeAttributesProvider(nodeAttributesProvider);
    }
    //node资源监控服务
    nodeResourceMonitor = createNodeResourceMonitor();
    addService(nodeResourceMonitor);
    ((NMContext) context).setNodeResourceMonitor(nodeResourceMonitor);
    //容器管理服务
    containerManager =
        createContainerManager(context, exec, del, nodeStatusUpdater,
        this.aclsManager, dirsHandler);
    addService(containerManager);
    ((NMContext) context).setContainerManager(containerManager);

    this.nmLogAggregationStatusTracker = createNMLogAggregationStatusTracker(
        context);
    addService(nmLogAggregationStatusTracker);
    ((NMContext)context).setNMLogAggregationStatusTracker(
        this.nmLogAggregationStatusTracker);
    
    //web通讯服务
    WebServer webServer = createWebServer(context, containerManager
        .getContainersMonitor(), this.aclsManager, dirsHandler);
    addService(webServer);
    ((NMContext) context).setWebServer(webServer);
    int maxAllocationsPerAMHeartbeat = conf.getInt(
        YarnConfiguration.OPP_CONTAINER_MAX_ALLOCATIONS_PER_AM_HEARTBEAT,
        YarnConfiguration.
            DEFAULT_OPP_CONTAINER_MAX_ALLOCATIONS_PER_AM_HEARTBEAT);
    ((NMContext) context).setQueueableContainerAllocator(
        new DistributedOpportunisticContainerAllocator(
            context.getContainerTokenSecretManager(),
            maxAllocationsPerAMHeartbeat));

    dispatcher.register(ContainerManagerEventType.class, containerManager);
    dispatcher.register(NodeManagerEventType.class, this);
    addService(dispatcher);

    pauseMonitor = new JvmPauseMonitor();
    addService(pauseMonitor);
    metrics.getJvmMetrics().setPauseMonitor(pauseMonitor);

    DefaultMetricsSystem.initialize("NodeManager");

    if (YarnConfiguration.timelineServiceV2Enabled(conf)) {
      this.nmCollectorService = createNMCollectorService(context);
      addService(nmCollectorService);
    }

    // StatusUpdater should be added last so that it get started last 
    // so that we make sure everything is up before registering with RM. 
    addService(nodeStatusUpdater);
    ((NMContext) context).setNodeStatusUpdater(nodeStatusUpdater);
    nmStore.setNodeStatusUpdater(nodeStatusUpdater);

    // 安全服务
    try {
      doSecureLogin();
    } catch (IOException e) {
      throw new YarnRuntimeException("Failed NodeManager login", e);
    }

    registerMXBean();

    context.getContainerExecutor().start();
    super.serviceInit(conf);
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值