YARN中的Service

来源:互联网 发布:微信矩阵的搭建 编辑:程序博客网 时间:2024/05/07 21:26
AggregatedLogDeletionService
会定期删掉 HDFS 目录 "yarn.nodemanager.remote-app-log-dir" 中的日志文件
运行作业时 NodeManager 会将作业写在本地,作业完成后文件被写入 HDFS 配置项"yarn.nodemanager.remote-app-log-dir" 指定的目录中。

AsyncDispatcher
在 MRAppMaster 中被创建
一个线程死循环(其实肯定有判断条件的,表达能力有限,以后就这么说了)从 队列eventQueue 中取出event 分发。
Map<Class<?extends Enum>, EventHandler>eventDispatchers
向 Dispatcher 注册就是 向变量 eventDispatchers中存入 事件类型和处理它的 handler
分发事件的时候 从 eventDispatchers中根据事件 type 取出对应的 handler 进行 处理就行了,具体就是
放到 handler 中的队列中就返回,具体处理就由这个handler 自己在独立的线程中从队列中取事件进行处理了。
教科书式的生产者-消费者模式。

LocalDirsHandlerService
周期性检查这两个配置项对应的本地目录是否正常,如检查文件是不是个目录或者存在不存在啊,能不能读啊,能不能写啊:
yarn.nodemanager.log-dirs; yarn.nodemanager.local-dirs
第一个配置是用来写容器的日志文件的。
启动容器前会先创建本地目录:${yarn.nodemanager.log-dirs}/applicationId/containerId,一个容器一个目录
第二个配置还没注意过,先把解释贴过来,改天再说:
List of directories to store localized files in. An application's localized file directory will be found in: 
${yarn.nodemanager.local-dirs}/usercache/${user}/appcache/application_${appid}. Individual containers' work directories, 
called container_${contid}, will be subdirectories of this

ContainerManager 协议的实现 ContainerManagerImpl
这个类中的 rpc 服务器的地址??
这应该是一个运行在NodeManager上的服务,接收 远程 ApplicationMaster 启动本节点容器的请求,启动本节点上的容器。
ApplicationMaster 使用ContainerManager 向 NodeManager 发送 StartContainerRequest  请求 NodeManager 启动一个容器。
ContainerManagerImpl 作为 ContainerManager 的实现,根据StartContainerRequest  中的信息
创建一个 ContainerImpl,存入 NMContext 对象的 containers<containerID, container>中
创建一个 Application(org.apache.hadoop.yarn.server.nodemanager.containermanager.application.Application),存入NMContext 的 
applications<ApplicationId, Application>中。
分别创建 ApplicationInitEvent 和 ApplicationContainerInitEvent,提交给 dispatcher。

org.apache.hadoop.mapreduce.v2.app.launcher.ContainerLauncherImpl
This class is responsible for launching of containers
启动远程 NameNode 上的 Container。
启动一个线程,死循环从服务类 ContainerLauncherImpl 的阻塞队列中取出 ContainerLauncherEvent 事件进行处理。
具体的事件处理过程:
为事件创建一个 EventProcessor ,这就是个组合了ContainerLauncherEvent 的Runnable,将它提交到线程池就OK了。
既然 EventProcessor 是个被丢在线程池中的 Runnable,那它总会被调度,它运行的时候根据 ContainerLauncherEvent 中的 ContainerId 从服务ContainerLauncherImpl中的 containers<ContainerId, Container> 中取出“假的”Container(org.apache.hadoop.mapreduce.v2.app.launcher.ContainerLauncherImpl.Container),
如果没有就创建一个并放进去。将ContainerLauncherEvent 转为ContainerRemoteLaunchEvent 交由这个“假的”Container 来 
使用 ContainerManager 协议远程启动 NameNode 上的Container,具体启动过程由上面这个服务 ContainerManagerImpl 来处理。
[注:启动远程NameNode上Container的方法 
org.apache.hadoop.mapreduce.v2.app.launcher.ContainerLauncherImpl.Container.launch(ContainerRemoteLaunchEvent event)]

ContainersLauncher
The launcher for the containers
它是个 Servlce 也是个 EventHandler,处理的事件类型是 ContainersLauncherEvent
这个服务不像其他服务那样创建独立的线程来提供服务或处理事件。
这个 Handler 处理事件的 handle方法:
处理两种类型的事件,容器启动和清除。
处理启动容器事件时,从 ContainersLauncherEvent 中取出 Container ,创建一个 ContainerLaunch ,这个 ContainerLaunch 是个Callable并且拥有Container。
将这个 Callable 提交到线程池,将线程池接收这个任务后返回的 Future 和 原始任务 ContainerLaunch 包装为 RunningContainer,
保存到这个服务 ContainersLauncher 的 map<ContainerId,RunningContainer> 结构的变量 running 中。
当这个 Callable 被调度时,它会使用 ContainerExecutor 启动它持有的 Container,这回是真的启动Container了,不是new一个Event 丢给 dispatcher就拉倒了,
不信你看 org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor.launchContainer(...) 的实现就知道了