深入理解 Hadoop (六)YARN核心设计理念与工作流程剖析

深入理解 Hadoop 系列文章已完结,总共七篇文章,直达链接:
深入理解 Hadoop (一)网络通信架构与源码浅析
深入理解 Hadoop (二)HDFS架构演进
深入理解 Hadoop (三)HDFS文件系统设计实现
深入理解 Hadoop (四)HDFS源码剖析
深入理解 Hadoop (五)YARN核心工作机制浅析
深入理解 Hadoop (六)YARN核心设计理念与工作流程剖析
深入理解 Hadoop (七)YARN资源管理和调度详解

YARN ResourceManager 核心设计

在这里插入图片描述

ResourceManager 基本职能

YARN 的 ResourceManager 是集群主节点,内部运行非常重要的三个 RPC 服务端,分别为 Client,ApplicationMaster,NodeManager 提供服务。
在这里插入图片描述
ResourceTracker:NodeManager 通过该 RPC 协议向 ResourceManager 注册、汇报节点健康状况和 Container 运行状态,并领取 ResourceManager 下达的命令,这些命令包括重新初始化、清理 Container 等。在该 RPC 协议中,ResourceManager 扮演 RPC Server 的角色(由内部组件ResourceTrackerService 实现),而 NodeManager 扮演 RPC Client 的角色,NodeManager 总是周期性地主动向 ResourceManager 发起请求,并通过领取下达给自己的命令。
ApplicationMasterProtocol:应用程序的 ApplicationMaster 通过该 RPC 协议向 ResourceManager 注册、申请资源和释放资源。在该协议中, ApplicationMaster 扮演 RPC Client 的角色,而 ResourceManager 扮演 RPC Server 的角色。
ApplicationClientProtocol:应用程序的客户端通过该 RPC 协议向 ResourceManager 提交应用程序、查询应用程序状态和控制应用程序(比如杀死应用程序)等。在该协议中,应用工程序客户端扮演 RPC Client 的角色,而 ResourceManager 扮演 RPC Server 的角色。

ResourceManager 内部组成

ResourceManager 内部的工作组件大致用一张图表示如下:
在这里插入图片描述

ResourceManager 事件与事件处理器

在这里插入图片描述
从事件驱动角度展示 ResourceManager 内部各类事件与事件处理器的相互关系:
在这里插入图片描述
ResourceManager 的中央调度器 AsyncDispatcher 应用到了 命令模式中介者模式

YARN NodeManager 核心设计

NodeManager(NM)是 YARN 中单个节点上的代理,它管理 Hadoop 集群中单个计算节点,功能包括与 ResourceManger 保持通信、管理 Container 的生命周期、监控每个 Container 的资源使用(内存、CPU 等)情况、追踪节点健康状况、管理日志和不同应用程序用到的附属服务(auxiliary service)。

NodeManager 基本职能

在这里插入图片描述
ResourceTrackerProtocol: NodeManager 通过该 RPC 协议向 ResourceManager 注册、汇报节点健康状况和 Container 运行状态,并领取 ResourceManager 下达的命令,包括重新初始化、清理 Container 占用资源等。在该 RPC 协议中,ResourceManager 扮演 RPC Server 的角色,而 NodeManager 扮演 RPC Client 的角色(由内部组件NodeStatusUpdater 实现),NodeManager 与 ResourceManager 之间采用了"pull模型", NodeManager 总是周期性地主动向ResourceManager发起请求,并领取下达给自己的命令。
ContainerManagementProtocol: 应用程序的 ApplicationMaster 通过该 RPC 协议向 NodeManager 发起针对 Container 的相关操作,包括启动 Container、杀死 Container、获取 Container 执行状态等。在该协议中,ApplicationMaster 扮演 RPC Client 的角色,而 NodeManager 扮演 RPC Server 的角色(由内部组件 ContainerManager 实现),换句话说,NodeManager 与 ApplicationMaster 之间采用了 “push模型”,ApplicationMaster 可以将 Container 相关操作第一时间告诉 NodeManager,相比于 “pull模型”,可大大降低时间延迟。

NodeManager 内部组成

在这里插入图片描述

NodeManager 事件和事件处理器

在这里插入图片描述
在这里插入图片描述

MapReduce On YARN 整体流程解析

不同计算引擎的 APPMaster 和 Task 实现:
在这里插入图片描述
在这里插入图片描述

  • 步骤 1:ApplicationClientProtocol.submitApplication
  • 步骤 2:ContainerManagementProtocol.startContainers,启动AM的命令行:java MRAppMaster
  • 步骤 3:launch ApplicationMaster
  • 步骤 4:ApplicationMasterProtocol.registerApplicationMaster
  • 步骤 5:ApplicationMasterProtocol.allocate
  • 步骤 6:ContainerManagementProtocol.startContainers,启动任务的命令行:java YarnChild
  • 步骤 7:launch Task
  • 步骤 8:TaskUmbilicalProtocal.heartbeat
  • 步骤 9:ApplicationMasterProtocol.finishApplicationMaster

上图中,四大跟 Container 有关的组件:

  • RM 中的 ApplicatoinMasterLauncher 负责发送RPC请求给 NM 来启动 AM(步骤 2)。
  • AM 中的 ContainerAllocator 负责发送 RPC 请求给 RM 去申请 Containter(步骤 5)。
  • AM 中的 ContainerLauncher 负责发送 RPC 请求给 NM 去启动 Container(步骤 6)。
  • NM 中的 ContainersLauncher 负责在 NM Server 端启动 Container(步骤 7)。

MapReduce Job 工作流程详解

YARN NodeManager 注册和心跳

NodeStatusUpdaterImpl 是 NodeManager 与 ResourceManager 通信(注册和心跳)的唯一通道,通信协议:ResourceTracker。
当 NodeManager 启动时, 该组件负责向 ResourceManager 注册,并汇报节点上总的可用资源( 该值在运行过程中不再汇报); 之后,该组件周期性与 ResourceManager 通信, 汇报各个 Container 的状态更新,包括节点上正运行的 Container、 已完成的 Container 等信息, 同时 ResourceManager 会为之返回待清理 Container 列表、 待清理应用程序列表、诊断信息、 各种 Token 等信息。

YARN NodeManager 注册

NodeStatusUpdaterImpl 在 NodeManager 的 serviceInit() 方法中进行构建,在 serviceStart() 方法中向 ResourceManager 注册。

YARN NodeManager 心跳

在 NodeStatusUpdaterImpl 的 serviceStart() 方法中,通过 registerWithRM() 方法完成 NodeManager 向 ResourceManager 的注册工作;之后调用 startStatusUpdater() 启动一个心跳线程。
不同组件的默认心跳时间:
YARN:1s
HDFS:3s
FLINK:10s

ResourceManager 中的 APPMasterService 接收到心跳命令后向调度器申请资源的逻辑用到了责任链模式

YARN AbstractLivelinessMonitor 验活机制

AbstractLivelinessMonitor 的过期处理方法 expire() 应用了模板方法模式,在不同的子类 AMLivelinessMonitor、ContainerAllocationExpirer、NMLivelinessMonitor 等采用了不同的处理逻辑。
expire(key) 方法在各个 AbstractLivelinessMonitor 的各个实现类的实现基本差不多,都是提交一个 Event 到 AsyncDispatcher 中。
NMLivelinessMonitor 的 expire(NodeId id) 方法定义:

dispatcher.handle(new RMNodeEvent(id, RMNodeEventType.EXPIRE));

AMLivelinessMonitor 的 expire() 方法的定义:

dispatcher.handle(new RMAppAttemptEvent(id, RMAppAttemptEventType.EXPIRE));

YARN ApplicationMaster 核心设计

ResourceManager 管理部分主要由三个服务构成,分别是 ApplicationMasterLauncherAMLivelinessMonitorApplicationMasterService,它们共同管理应用程序的 ApplicationMaster 的生存周期。

  • ApplicationMasterLauncher: ApplicationMasterLauncher 既是一个服务,也是一个事件处理器,它处理 AMLauncherEvent 类型的事件,该类型事件有两种,分别是请求启动一个 ApplicationMaster 的 “LAUNCH” 事件和请求清理一个 ApplicationMaster 的 “CLEANUP” 事件。ApplicationMasterLauncher 维护了一个线程池,从而能够尽快地处理这两种事件。
  • AMLivelinessMonitor:该服务周期性遍历所有应用程序的 ApplicationMaster,如果一个ApplicationMaster 在一定时间(可通过参数yarn.am.livenessmonitor.expiry-interval-ms 配置,默认为10min)内未汇报心跳信息,则认为它死掉了,它上面所有正在运行的 Container 将被置为运行失败。
  • ApplicationMasterService:ApplicationMasterService 实现了RPC协议 ApplicationMasterProtocol,负责处理来自 ApplicationMaster 的请求,请求主要包括 注册、心跳和 清理 三种。
    在这里插入图片描述
  • 步骤1:用户向 YARN ResourceManager 提交应用程序,ResourceManager 收到提交请求后,先向资源调度器申请用以启动 ApplicationMaster 的资源,待申请到资源后,再由 ApplicationMasterLauncher 与对应的 NodeManager 通信,从而启动应用程序的 ApplicationMaster。
  • 步骤2:ApplicationMaster 启动完成后,ApplicationMasterLauncher 会通过事件的形式,将刚刚启动的 ApplicationMaster 注册到 AMLivelinessMonitor 以启动心跳监控。
  • 步骤3:ApplicationMaster 启动后,先向 ApplicationMasterService 注册,并将自己所在 host、端口号等信息汇报给它。
  • 步骤4:ApplicationMaster 运行过程中,周期性地向 ApplicationMasterService 汇报"心跳" 信息(“心跳” 信息中包含想要申请的资源描述)。
  • 步骤5:ApplicationMasterService 每次收到 ApplicationMaster 的心跳信息后,将通知 AMLivelinessMonitor 更新该应用程序的最近汇报心跳的时间。
  • 步骤6:当应用程序运行完成后,ApplicationMaster 向 ApplicationMasterService 发送请求,注销自己。
  • 步骤7:ApplicationMasterService 收到注销请求后,标注应用程序运行状态为完成,同时通知 AMLivelinessMonitor 移除对它的心跳监控。

上图中前 3 步详细状态机图如下:
在这里插入图片描述

MRAppMaster 启动逻辑

MRAppMaster 中,最重要的组件:
第一组:RPC 服务端:TaskAttemptListener + ClientService
第二组:RPC 客户端:ContainerAllocator + ContainerLauncher(Container 工作组件)
在这里插入图片描述
在提交 JobEventType.JOB_START 事件之前,都是在做准备。当提交 JobEventType. JOB_START 事件时,意味着 Job 开始执行了。
关于后续的三个重点:

  • ContainerAllocator 存在于 AM 中,负责跟 RM 打交道,去申请 Contianer 资源的。同时由于申请 Container 是通过 心跳完成的,所以也就是说:ContainerAllocator 组件同时完成 ApplicationMaster 向 RM 维持心跳的工作。
  • ContainerLauncher 存在于 AM 中,负责跟 NM 打交道,发送 RPC 请求给 NM 去启动 Container,这个 Container 内就是用来启动 MapTask 或者ReduceTask 的
  • ContainersLauncher 组件是存在于 NM 中的,专门用来在本地执行 ShellCommad 来启动 YARNChild JVM。

ContainerAllocator 工作机制:申请 Container

ContainerAllocator 的具体实现是:ContainerAllocatorRouter
注意在处理 MapTask 和 ReduceTask 的区别。MapTask 的 container 申请请求,是存放在 scheduledRequests 队列中的,但是 reduceTask 的 Container 申请请求是存放在 pendingReduces 队列中的。因为按照 MapReduce 的运行逻辑,肯定是先满足 MapReduce 第一阶段 MapTask 的 Container 申请请求,然后再去满足 第二阶段的 ReduceTask 的 Container 申请请求。
在这里插入图片描述
RMContainerAllocator 是 RMCommunicator 的实现类,而 RMCommunicator 也是一个 Service,同样也会调用 serviceStart() 方法来执行启动。RMCommunicator 则负责了注册、心跳请求的实际发送。
整体来说,ContainerAllocatorRouter 负责 MRAppMaster 向 RM 申请 Container 的工作,具体的原理是:ContainerAllocatorRouter 父类中的 AllocatorRunnable 这个线程每隔 1s 向 ResourceManager 发送心跳,同时申请 Container 资源。然后完成 Task 和 Container 的分派工作。
在 ApplicationMaster 中负责进行 Container 申请的组件就是: ContainerAllocator , 真正创建的是 ContainerAllocatorRouter,这个组件的内部,负责完成工作的是: RMContainerRequestor。大部分的工作都在父类 RMCommunicator 中完成。两个重点:

  • 注册: 发送 RPC 请求给 RM
  • 心跳: 启动一个线程,每隔 1s 执行 heartbeat()
    • 发送 allocate RPC 请求给 RM 申请 container,也可以认为是 心跳请求的具体实现。
    • 将申请的 container 完成和 container 申请请求的映射。

最后的结果:哪个 Task 用那个 Contianer 去执行 这个关系就被维护在 两个 Map 中: maps、reduces。

ContainerLauncher 工作机制:启动 Container

工作机制简单描述: 内部为了一个事件队列和一个消费线程。如果其他组件提交一个事件给这个 ContainerLauncher 处理的话,其实就是提交一个事件到队列中。然后消费线程取到事件之后,生成一个 任务 EventProcessor 提交打到线程池中执行。这个 EventProcessor 的职责是 发送 RPC 请求给 NM 让他启动 Container。ContainerLauncher 的具体实现是 ContainerLauncherRouter,它既是一个 Service 也是一个 EnventHandler。
在这里插入图片描述
接下来发送 RPC 请求让 NodeManager 去启动 Container。对于 MapReduce 来说,启动 Container 之后,他里面运行的 JVM 进程是 YarnChild,有可能运行的是 MapTask,有可能运行的是 ReduceTask。

ContainersLauncher 工作机制

ContainersLauncher 是存在于 NodeManager 之上 ContainerManagerImpl 组件的一个内部组件,作用是用来启动 Container 的。
在这里插入图片描述
ContainersLauncher 是一个 Service,也是一个 EventHandler,接收 ContainersLauncherEvent 事件执行处理,比如:LAUNCH_CONTAINER,创建一个ContainerLaunch 任务提交到 ContainersLauncher 内的线程池中,用来启动一个 Container:YarnChild。这个 JVM 的作用就是用来执行 MapTask 或者 ReduceTask。

补充说明

MapReduce 中的 map 方法、reduce 方法应用了 模板方法模式。新 API 中 Mapper 多了默认实现类,位于 mapreduce 包(老 api 位于 mapred 包),新 API 中 map 方法的默认实现逻辑即原样输出,也即 接口适配器模式

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值