3.2 Hadoop系统的结构
在上述计算机集群的基础上,Hadoop建立起HDFS和YARN两个子系统。前者是文件系统,管数据存储;后者是计算框架,管数据处理。
如果只有HDFS而没有YARN,那么Hadoop集群可以被用作容错的文件服务器,别的就没有什么应用可言了。虽然HDFS是个分布式的文件系统,但是对服务器的用户来说那只是它的内部实现,从外部看与一般基于Raid结构的文件服务器并无多大区别。
然而,加上了YARN情况就不同了。从功能和层次上看,YARN是HDFS的用户,是HDFS的上一层,YARN的功能和作用是建立在HDFS基础上的,HDFS提供数据供YARN子系统处理和计算。这样,HDFS的价值通过YARN又得到了进一步的体现,这个价值远远超过了它作为一般文件服务器所具有的价值。与一般游离于文件服务器外部、通过网络(无论其为广域网、局域网或储域网)与服务器相连的应用相比,YARN代表着一种新的计算模式。在传统的“客户/服务”模式中,计算在哪里进行,就把数据(通过网络)搬运到哪里。而YARN所实现的模式却是:数据在哪里,计算就在哪里进行;YARN子系统里的计算就好像溶化在HDFS所在的集群中一样。传统的“客户/服务”模式是哑铃状的集中存储加集中计算,而Hadoop的模式是“溶化”式的、“打成一片”的分布存储加分布计算。显然,对于大数据处理,后者的效率(从而其价值)比前者要大得多。
这两个子系统都是分布式的,但都是主从式分布。HDFS子系统中有主节点和从节点, YARN子系统中也有主节点和从节点。主节点管理着从节点,并对外代表着整个子系统。所谓对外,主要是对使用人。比方说,使用人要提交一个进行数据处理的作业(Job),就只跟YARN子系统的主节点打交道,而不直接跟任何一个从节点打交道;即使他正在某个从节点的终端上,也只是借由这个从节点跟主节点打交道。同样,如果使用人要将一文件复制到HDFS中,也首先要跟HDFS的主节点打交道,然后在主节点的安排和指引下将文件内容传递到某些从节点上。主、从节点之间的关系,就好像“中央”与“地方”的关系。之所以说主/从,而不说主/次,就是要突出这种上下级的管理/被管理的关系。
YARN和HDFS是同一个集群上的两个子系统,但这并不意味着把集群中的节点机器划分成两个集合,分别用于两个子系统;而是集群中的每个节点机器都扮演着两种角色,打着两份工。所以,当我们说某台节点机器是HDFS的一个从节点时,它也许(多半)又是YARN的从节点,但也不排除恰巧是YARN主节点的可能。
起着HDFS主节点作用的是一个NameNode对象,更确切地说是一个运行着NameNode类代码的Java虚拟机(JVM),再确切一点说是节点机器上的一个运行着NameNode的JVM进程。NameNode类是有主函数main()的。同样,起着HDFS从节点作用的是DataNode对象,这也是JVM进程,DataNode类也是有主函数main()的。虽然NameNode和DataNode只是在某个节点机器上运行的对象,其本身并非物理意义上的节点,但我们将其当成HDFS子系统的逻辑意义上的节点。
起着YARN主节点作用的是一个ResourceManager对象,也是一个JVM进程;起着YARN从节点作用的是NodeManager对象,也是JVM进程。当然,这两个类都有主函数main()。同样,我们也称ResourceManager和NodeManager对象为节点,因为它们是YARN子系统的逻辑意义上的节点。
不过,起着YARN主节点作用的是ResourceManager,并不意味着其所在的节点机器上只能有这么一个进程属于YARN子系统。同样,NodeManager所在的节点机器上也未必只有一个进程属于YARN子系统。无论是ResourceManager还是NodeManager,都可以再创建别的进程。例如Mapper和Reducer就都是独立存在的JVM进程,它们都属于YARN子系统,却并非ResourceManager或NodeManager的内部成分。这样,假定集群中的某个机器节点在两个子系统中都是从节点,并且上面又运行着一个Mapper,那么这台机器上至少运行着三个独立存在的Java虚拟机进程,分别执行着NodeManager、DataNode和Mapper三个class的程序。当然,实际的情况还要更复杂。
至于同一进程内部的多个线程,那就更不用说了。
就这样,HDFS的主节点NameNode管理着集群中所有的DataNode, YARN的主节点ResourceManager管理着集群中所有的NodeManager。但是这二者又有上下层之分,当我们说到一个Hadoop集群、Hadoop平台的时候,更多的是指其YARN子系统。我们要在Hadoop上运行的应用,更多的是大数据处理而不是大数据存储。而YARN子系统的主体,则是其MapReduce框架。
YARN的计算模式是“数据在哪里,计算就在哪里”;但是又说跟文件系统打交道就得跟其主节点NameNode打交道。那是否计算就只能在HDFS的主节点上进行,或者虽然计算可以在从节点上进行,但所有的数据都得流经主节点呢?当然不是。我们不妨打个比方,把HDFS设想成一个大型仓储系统,这个系统的仓库散布在全国各地,但是由总部统一管理,账本都在总部,各仓库凭总部开出的提货单发货。现在YARN接到一个大型任务(“作业”),要进行某方面的加工提炼。它首先要搞清楚需要一些什么原材料,然后就跟仓储总部联系,搞清楚这些原材料都存放在哪些仓库中,并开好提货单。有了这些,YARN就可以把加工厂开到一个个有关仓库的当地,以便就地提货,就地加工,边提货边加工。即使仓库当地挤不下了,也要把加工厂开在尽量靠近的地方,以减少运输开销。另一方面,既然提货单已在手上,就不需要事事都跟总部打交道了。这里的仓储总部相当于NameNode,一个个具体的仓库就像DataNode; YARN需要从NameNode得到的只是类似于“介绍信”、“提货单”那样的东西。至于尽量要开到仓库当地的加工厂,那就是Mapper和Reducer,那也都是独立的JVM进程。