大数据处理系统:Hadoop源代码情景分析
上QQ阅读APP看书,第一时间看更新

1.8 Hadoop的由来和发展

2004年前后,Google公开发表了三篇论文,报道了Google内部正在使用的三项大数据处理技术。其中一篇是关于MapReduce的,一篇是关于面向集群的分布式文件系统的,还有一篇介绍了一种称为BigTable的分布式非SQL数据库。三篇论文围绕着一个中心,就是如何在一个由大量普通商品计算机(特别是价格不贵的PC机)构成的集群上进行大数据处理。在此之前,人们普遍认为大数据处理一定得有价格昂贵的大型机和专用机才能胜任,PC一类的普通商品计算机是用不上的。

这三篇论文引起了广泛的注意和兴趣。因为Google是互联网应用的龙头企业,在实际运营中积累了海量的数据,对于什么样的技术可以或比较适合用于这方面的大数据处理,它自然是“春江水暖鸭先知”。特别是关于MapReduce的那篇论文,使人们了解到:原来被认为是简单到令人尴尬的“embarrassingly parallel”或曰“极简并行”,在互联网相关的大数据处理方面竟已大有用武之地,已经可以用来解决许多问题。换言之,对于互联网相关的大数据处理,在相当程度上有MapReduce就可以应付了。

于是很快就有了立足于前两篇论文的大数据处理平台开源项目,这就是Hadoop。至于第三篇论文,则有了基于Hadoop平台的分布式非SQL数据库开源项目HBase,意为Hadoop上的数据库。早期的Hadoop,直到2.0版之前,在数据流方面仅仅支持MapReduce的拓扑和结构,但是2.0版之后已经开始多样化。

Hadoop是一种主要面向MapReduce的大数据处理平台,或者说是一个面向MapReduce的大数据处理系统的框架,这个框架中什么都有,就剩下针对具体应用的Mapper和Reducer两个模块的位置留待用户自己提供,这两个模块必须是按规定interface实现的Java类。把用户开发的Mapper和Reducer嵌入这个框架,就构成一个针对具体应用的、基于MapReduce的大数据处理系统。具体的Mapper和Reducer尽可以换,Mapper和Reducer的数量即Map阶段和Reducer阶段的并行度也可以分别指定,但是数据流的拓扑是固定的,那就是两个节点的链状数据流,这是由框架的结构决定的。

另一方面,Hadoop是面向计算机集群的。虽然在单机上也可以运行,但是Hadoop的设计目标是针对计算机集群的(要不然就不用这么复杂了),集群的规模可大可小,小则三五台,大则数千台甚至更多。整个集群连成一个局域网,各节点机上的操作系统一般都是Linux, Hadoop就架设在Linux上面(Hadoop也有Windows版的),把这些节点机连在一起构成统一的处理平台。

除MapReduce框架之外,Hadoop还提供了一个容错的分布式文件系统HDFS,这是Hadoop除MapReduce之外的另一个子系统。显然这两个子系统分别对应着Google的两篇论文。HDFS是以各宿主机的文件系统为基础、为支撑的,但是宿主机的文件系统只是本地的、局部的,而HDFS是全局的,HDFS的一个“记录块”对于宿主文件系统而言就是一个文件。HDFS文件以记录块为单位分布在许多节点上,在对文件中的数据进行处理的时候,数据存放在哪里,计算(Map计算)就在哪里进行,而不是把数据远程调运过来供计算之用。当然,这需要有HDFS与MapReduce两个子系统之间的协调。

这样,单机操作系统如Linux是Hadoop的宿主,而Hadoop是对宿主的延伸和扩充。所以某种意义上Hadoop是对单机操作系统的延伸,实质上就是一个集群操作系统。

在Hadoop的发展历程中,2.0版的推出有着里程碑的意义。首先,此前的Hadoop只支持MapReduce一种模式、一种拓扑,并且其Mapper和Reducer必须是用Java语言写成的类(class);而2.0版之后则也可以支持别的链状拓扑,并且不再限于使用Java类。更重要的改变是,Hadoop的2.0版引入了一种新的作业管理机制,称为YARN,将作业管理的权力下放,把原先集中在主节点上的作业管理分布到基层,使集群中各节点的负载变得更均匀,也使集群的运行变得更健壮。

Hadoop的程序是用Java语言编写的。应该说这不失为一个正确的选择,因为Java的执行效率虽然是比C/C++低,但是却以此为代价换来了许多好处。其中最重要的是Java语言显著降低了编程的难度,显著降低了对于程序员技术水平的要求,从而能显著加快程序员们的研发进度并显著提高“成品率”。不妨举个例子。在需要连续运行的那些软件的开发中,内存管理是个颇为头疼的问题,一不小心就会有内存泄漏,就是软件运行时分配到了内存,但使用后没有归还。有内存泄漏的软件,如果在使用中只是短暂运行,或小规模运行,那倒也不至于有问题,很可能不会被察觉,因为程序的运行没等内存泄漏到很严重的地步就完成了,程序一结束,进程一退出运行,就一了百了,把问题掩盖过去了,操作系统会处理进程的善后事宜,把所占的内存全部释放。但是如果是长时间运行,或大规模运行(海量的数据需要处理),内存的泄漏问题就“纸包不住火”了,哪怕很小的泄漏也会很快积累起来。但是,如果采用Java语言编辑,这问题就不用程序员操心了,因为Java语言的废料回收(garbage collection)机制自会处理释放内存的问题。这就使程序员省心了,对程序员技术水平的要求当然也就降低了。除内存管理之外,后面我们将看到,Java语言中的“反射(reflect)”、“标注(annotation)”等,也是C/C++不提供但却很有用的机制。总的来说,C/C++是面向精英的,水平高超的程序员可以用C/C++写出十分精炼而高效的程序,但其入门的门槛却比较高。而Java是面向普通程序员的,难度相对较小,不过程序的执行效率和空间效率都要低一些。在计算机硬件的性能规格大大上升而价格大大下降、劳动力紧缺并且成本上升后的今天,以牺牲一些性能为代价换取程序的可靠性并降低对程序员的技术能力要求,显然是合理的、有利的。