我们知道,Hadoop主要由三部分组成,除了之前说的MapReduce,还有分布式文件存储系统HDFS,和分布式集群资源调度框架Yarn。本篇专栏就来主要的来说一下Yarn框架,它使Hadoop从一个单一的大数据计算引擎,成为了一个集存储,计算,资源管理为一体的大数据平台,进而发展出自己的大数据体系。
Yarn的发展
首先我们来看一下,单纯MapReduce的架构思路:MapReduce最核心的就是JobTracker与TaskTracker相互之间的通信,由JobTracker分派任务,监控TaskTracker完成任务。
这样有什么缺点吗?
这样服务器的资源调度和MapReduce的执行过程耦合在一起,如果想要在在当前集群中运行其他任务,比如Spark或者Storm,就无法共同使用这个过程中的资源了。
Yarn作为一种资源调度器,架构图如下:
从图中我们可以看出,Yarn分为两个部分,一个是资源管理器(Resource Manager),一个是节点管理器(Node Manager)。这也是我们经常会起的两种集群,ResourceManager进程主要负责整个集群的资源调度管理,通常部署在独立的服务器上。NodeManager进程负责的是具体服务器上的资源管理,在集群的每一台计算服务器上都会启动,基本与HDFS的DataNode一起出现。
这也就是上篇专栏说的,相同的架构模式:一主多从。
ResourceManager
具体来说,ResourceManager又包括两个组件:调度器和应用程序管理器。
<1> 调度器
调度器其实就是一个资源分配算法,根据Client提交的资源申请和当前服务器集群的资源状况进行资源分配。Yarn内置了几种调度器算法:Fair Scheduler、Capacity Scheduler等等,当然也可以自己写这个调度算法。
Yarn进行资源调度的单位是容器(Container),每个容器都有自己的内存,CPU计算资源。默认配置下,都是一核的。这个容器由NodeManager启动和管理,然后实时收集相关信息告诉给ResourceManager。
<2>应用程序管理器
应用程序管理器主要负责程序的提交,监控应用程序的运行状态等等。应用程序启动之后,会首先在集群中默默启动一个东西,叫ApplicationMaster,ApplicationMaster也需要运行在容器里面。
而ApplicationMaster会在程序运行的时候,按照需求,去找ResourceManager申请容器资源,然后分发自己的应用程序代码到容器上进行分布式计算。
以一个MapReduce程序为例,让我们来看看Yarn的工作流程
- 我们向Yarn提交应用程序,包括MapReduce 的 ApplicationMaster 、 MapReduce的程序本身,以及MapReduce Application启动的指令。
- 由ResourceManager 去和NodeManager通信,根据集群资源,为用户分配第一个容器,并且将MapReduce 的 ApplicationMaster分发到这个容器上启动。
- MapReduce 的 ApplicationMaster启动后立刻向ResourceManager进程进行注册,并且申请运算需要的容器资源。
- MapReduceApplicationMaster申请到需要的容器资源之后,立刻去找自己节点对应的NodeManager通信,将MapReduce程序分发给NodeManager,然后在容器中运行,运行的是Map或者Reduce任务。
- Map或者Reduce任务在运行期,和MapReduce 的 ApplicationMaster进行通信,汇报自己的运行状态,如果运行结束,MapReduce 的 ApplicationMaster就会向ResourceManager进程注销并且释放所有的容器资源。
MapReduce如果想要在Yarn上运行,就需要遵循MapReduce ApplicationMaster的规范,并且,不仅仅是MapReduce,其他的像spark storm也一样,也需要遵循yarn规范的xxx Application Master,这样就实现了并发执行各种各样不同的大数据计算框架,实现资源的统一管理。
那么还有一个问题:为什么HDFS是系统,MapReduce和Yarn都是框架?
那是因为,框架在设计的思路上有一个重要的设计原则,叫“依赖倒转原则”,依赖倒转原则是高层模块不能依赖低层模块,他们应该共同依赖一个抽象,这个抽象由高层模块定义,由低层模块实现,就像,一主多从一样。
那么,什么是高层模块,什么是底层模块?
以JavaWeb为例:
- 用户从前端发送请求之后,最先处理这些请求的是像Tomcat Jetty这些JavaWeb容器,通过监听80端口,将HTTP请求以二进制流封装成为request对象。
- 然后到达SpringMVC框架,把Request里面的用户参数抽取出来,根据URL给予对应的Model对象处理。
- 紧接着,在应用程序处理用户请求,完成实际业务,这就又分为了服务层和数据持久层。
在这个例子中,Tomcat相对于SpringMVC就是高层模块,相对于我们的应用程序也是高层模块。
但是Tomcat并不依赖于这二者,但虽然不依赖,但是却可以做到线相互通信,这是为什么?
因为Tomcat和SpringMVC都依赖于J2EE规范,SpringMVC还实现了J2EE规范的HTTPServlet抽象类,也就是DispatchServlet,配置在Web.xml中。这样Tomcat就可以使用DispatchServlet处理用户请求了。
同样,SpringMVC也不依赖于应用程序,也就是Java代码,而是通过依赖SpringMVC的配置文件或者Annotation抽象,来调用Java代码。
所以,Tomcat和SpringMVC都算是框架。
然后回来说MapReduce和Yarn。
我们通过实现Map Redce接口,遵循MapReduce的编程规范,就可以实现分布式计算了。实现了Yarn的接口规范,就可以被yarn调度管理,统一安排服务器资源,所以这二者都是框架。
相反地,HDFS就不是框架,使用HDFS就是直接调用HDFS提供的API接口,HDFS作为底层模 块被直接依赖。