「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
推荐阅读时间:10分钟
字数:1357字
YARN Server工作机制深度剖析
YARN的核心设计理念是服务化(Service) 和事件驱动AsyncDispatcher ( Event + EventHandler/StateMachine) 。服务化和事件驱动软件设计思想的引入,使得YARN具有低耦合、高内聚的特点,各个模块只需完成各自功能,而模块之间则采用事件联系起来,系统设计简单且维护方便。这种编程方式具有异步、并发等特点,更高效,更适合大型分布式系统。
Service在Yarn源码中处处可见,想要阅读源码就得选了解YARN中的Service机制
下面就详细介绍下什么是Service
对于生命周期较长的对象,YARN 采用了基于服务的对象管理模型对其进行管理,该模型主要有以下几个特点。
- 将每个被服务化的对象分为 4 个状态:NOTINITED(被创建)、INITED(已初始化)、STARTED(已启动)、STOPPED(已停止)。
- 任何服务状态变化都可以触发另外一些动作。
- 可通过组合的方式对任意服务进行组合,以便进行统一管理。通俗的解释:一个大 Service 可能会有一堆子 Service
使用场景化驱动的方式来了解YARN Service
我们比较熟悉的ResourceManager其实就是一个Service,它本身就是Service的子类,下面是ResourceManager和NodeManager类的继承类图:
根据类的继承关系,直接看接口Service,接口的具体信息如下:
- 印证了Service都有四个状态:NOTINITED、INITED、STARTED、STOPPED
- 于此同时还有五个重要的方法:构造方法、init()、start()、stop()、close()
1 | java复制代码public interface Service extends Closeable { |
这四个状态和五个重要的方法之间有不可分割的关系:
了解了Service的主要信息之后,下面从上往下查看各类的具体信息
对于AbstractService类,它实现了结构Service,那么它一定会对上述的四个方法进行实现
1 | java复制代码public abstract class AbstractService implements Service { |
通过源码可以看到,虽然对四个方法都已经进行了实现但是都是空实现,这是为什么呢?
使用一个中间类去对父类的方法进行空实现,然后真正的子类去继承中间类,这样可以避免子类去实现父类的一些不必要的方法,此处AbstractService就是中间类,这样的代码设计模式是可以借鉴的
既然AbstractService对这四个方法没有进行实现,下面就来看它的子类CompositeService,来看CompositeService类的具体定义:
- 一个ArrayList,它是一个Service类型的集合,印证了上面的特点:一个大 Service 可能会有一堆子 Service
此处是ArrayList说明Service加入的顺序是保留了下来的,是有顺序的
1 | java复制代码private final List<Service> serviceList = new ArrayList<Service>(); |
- 从ArrayList中获取Service,上述已经说明列表保留了服务的顺序,由此此处获取Service也是有顺序的
1 | java复制代码public List<Service> getServices() { |
- 添加子 service 的方法
1 | java复制代码protected void addService(Service service) { |
- 针对所有 Service 执行 init 初始化:最终调用 service 的 () 方法
针对所有 Service 执行 start 启动:最终调用 service 的 serviceStart() 方法
1 | java复制代码protected void serviceInit(Configuration conf) throws Exception { |
下面看到ResourceManager,它是CompositeService的子类,它实现了方法serviceInit()、serviceStart()、serviceStop()
当ResourceManager进行初始化、开启的时候会调用父类的init、start方法,然后这两个方法再调用本部类重写了的serviceInit()、serviceStart()方法,从而完成具体业务逻辑。
1 | java复制代码ResourceManager.main(){ |
总而言之,在 YARN 中,会有非常非常多的 Service,每个 service 都要初始化和启动,如果Service本身有serviceInit、serviceStart方法,就各自做自己的实现,否则使用父类的实现。
如果阅读 Service 组件的源码,从下面三方面入手:
- 构造方法
- serviceInit() 方法
- serviceStart() 方法
本人在学习的路上,上述文章如有错误还请指教批评。
本文转载自: 掘金