AggregatedLogDeletionService


"yarn.nodemanager.remote-app-log-dir" 中的日志文件


运行作业时 NodeManager 会将作业写在本地,作业完成后文件被写入 HDFS 配置项"yarn.nodemanager.remote-app-log-dir" 指定的目录中。




AsyncDispatcher

在 MRAppMaster 中被创建



死循环(其实肯定有判断条件的,表达能力有限,以后就这么说了)从 队列 eventQueue



Map<Class<?extends Enum>, EventHandler>eventDispatchers



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



ContainerManagerImpl


这个类中的 rpc 服务器的地址??


这应该是一个运行在NodeManager上的服务,接收 远程 ApplicationMaster 启动本节点容器的请求,启动本节点上的容器。


ApplicationMaster 使用ContainerManager 向 NodeManager 发送 StartContainerRequest  请求


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了。


既然 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(...) 的实现就知道了