大数据架构商业之路:从业务需求到技术方案
上QQ阅读APP看书,第一时间看更新


3.1.1 Hadoop和HDFS

在第2章介绍Apache Nutch的时候,就曾提到过Hadoop起源于Nutch。2003年,Google发表了一篇论文描述他们的分布式文件系统GFS(Google File System),为Nutch攻克数十亿网页的存储难题提供了方向。Nutch和Lucene的创始人Doug Cutting受到启发,和团队一起开发了Nutch的分布式文件系统NDFS(Nutch Distributed File System)。2004年,Google又发表了一篇重量级的论文《MapReduce:在大规模集群上的简化数据处理》(“MapReduce:Simplified Data Processing on Large Clusters”)。之后,Doug Cutting等人开始尝试实现论文所阐述的计算框架MapReduce。此外,为了更好地支持该框架,他们还将其与NDFS相结合。2006年,该项目从Nutch搜索引擎中独立出来,成为如今的Hadoop(http://hadoop.apache.org)。两年之后,Hadoop已经发展成为Apache基金会的顶级项目,并应用到很多著名的互联网公司中,目前其最新的版本是2.x由于历史的原因,Hadoop的版本号有点复杂,同时存在0.x、1.x和2.x,具体可以参见Apache的官网。

如今的Hadoop系统已经可以让使用者轻松地架构分布式存储平台了,开发和运行大规模的数据处理应用,其主要优势如下。

  • 透明性:使用者可以在不了解Hadoop分布式底层细节的情况下,开发分布式程序,充分利用集群的威力进行高速运算和存储。
  • 高扩展性:扩展分为纵向扩展和横向扩展,纵向扩展将增加单机的资源,总会达到瓶颈;而横向将增加集群中的机器数量,获得近似线性增加的性能,不容易达到瓶颈。Hadoop集群中的节点资源,采用的就是横向方式,可以方便地进行扩充,并获得显著的性能提升。
  • 高效性:由于采用了多个资源并行处理,使得Hadoop不再受限于单机操作(特别是较慢的磁盘I/O读写),可以快速地完成大规模的任务。加上其所具有的可扩展性,随着硬件资源的增加,性能将会得到进一步的提升。
  • 高容错和高可靠性:Hadoop中的数据都有多处备份,如果数据发生丢失或损坏,能够自动从其他副本(Replication)进行复原。同理,失败的计算任务也可以分配到新的资源节点,进行自动重试。
  • 低成本:正是因为Hadoop有良好的扩展性和容错性,所以没有必要再为其添置昂贵的高端服务器。廉价的硬件,甚至是个人计算机都可以成为资源节点。

Hadoop的发展历史决定了Hadoop框架的最核心元素就是HDFS和MapReduce。HDFS为海量的数据提供了存储,而MapReduce为海量的数据提供了计算。本章将侧重于HDFS的介绍,更多关于MapReduce的介绍将放在第4章,该章节专门讨论数据的处理。

HDFS是受到Google的大型分布式文件系统GFS的启发而开发出来的。Google的数据中心采用了廉价的Linux PC服务器构建集群,而GFS正是这个数据中心的存储系统,它隐藏了底层的负载均衡、切片备份等实现细节,让复杂性透明化,并提供了统一的文件系统访问接口。由于一脉相承,HDFS也有类似于GFS的特性和架构,适合部署在低廉的硬件上,容错性也比较高。同时,它还能提供高吞吐量的读取,适合那些有着超大数据集的应用场景。

为了更好地理解HDFS的体系架构,让我们先思考一个虚拟的案例:假设有一个名叫Hadoop的快消品公司,专门采用Flume公司提供的水源来生产各式饮用水和饮料,每天都有大量的纯净水通过Flume公司的车队运送到Hadoop公司的仓库。起初,Hadoop公司的规模并不大,一个仓库就足以满足业务的生产需求。随着市场的不断扩张,业绩蒸蒸日上,仓库已经无法放下更多的原材料了。但这个仓库建在市区,周边没有多余的空地供仓库扩建,如果再购买市区现有的其他仓库,成本又太高。怎么办呢?公司的高层想到了在市区周围的几个郊县再多建几处仓库。10多个仓库盖好了,生产的原材料有了足够的场地可以存放。可是这个时候Flume公司傻眼了,我们的纯净水到底要发往哪个仓库呢?如果不确定清楚,就有可能出现这样的情况:送到1号仓库,发现1号已经满仓,无法收货,而2号、3号和4号仓库等却都是空的。为了便于协调,Hadoop公司又成立了专门的仓库管理部门,负责收集各个仓库的负载情况,并及时与Flume公司的运输队进行沟通,整个流程渐渐变得顺畅。可是好景不长,高层很快发现了新的问题。原来,生产不同的饮料需要不同类型的水源,之前的做法是将某类水固定地存放在指定的仓库,例如A类水永远存放在3号仓。但是3号仓库总是发生意外状况,不是被小偷盗窃,就是大型储水桶发生渗漏,结果导致某些饮料的生产常常被耽误。该怎么办呢?类似的情况,将来会不会也发生在其他仓库呢?高层领导伤透了脑筋。关键的时刻,有人献上了妙计:要改变这种固定存放的模式,A类水分批放在3号、6号和8号库。这样,即使3号库的A类纯净水缺货,还可以从6号和8号库及时调拨,不至于影响饮料的生产。然后,再从Flume公司购买新的A类水放入3号库。这个策略果然生效,停产的风险大大降低,之后其他仓库发生类似的问题时也通过这个方案得到了很好的解决。

这个案例很容易理解,从中可以总结出如下3种行为:扩建仓库、增加协同部门和多仓备货。其实,HDFS架构和仓库的原理非常类似,下面看看这三种行为,分别对应于HDFS的哪些概念。

  • 扩建仓库:单个仓库的扩建,就是所谓的纵向扩展。纵向扩展很容易达到瓶颈,建立仓库是这样,计算机系统也同样如此。例如单机的硬盘和内存,不可能无限制地被加大。这时就需要考虑横向扩展了,在郊区新建一个仓库,在计算机系统中就是增加新的机器作为资源节点,不过这些机器节点存储的不再是纯净水,而是数据。在HDFS中,这些存储数据的节点被称为数据节点(Data Node)。
  • 增加协调部门:协同部门可以实时收集各个仓库的运作情况,并决策将进货存放在哪里更为合适。在HDFS中,扮演这个角色的节点称为命名节点(Name Node),它维护着系统中的大量元数据,负责管理文件系统的命名空间(Name Space)和控制外部的访问,包括打开、关闭、重命名文件或目录,将数据块映射到具体的数据节点等。随着协同部门职能重要性的日益增加,总公司可能还会将其管理内容进行备份,这就是次要命名节点(Secondary Name Node)。次要命名节点和命名节点的区别在于,它不会与数据节点和其他任务节点沟通,也不接收HDFS上的任何变化记录。次要命名节点最主要的目标就是与命名节点通信,根据配置定期地获取命名节点上的HDFS元数据快照,因此效率是非常高的。
  • 在多个仓库中进行备货:意外总是会发生,为了防止意外导致缺货的情况发生,可以采用的一项策略是将货物存储在多地的仓库中。在HDFS中也有同样的理念,这就是备份或副本(Replication)。存储在数据节点上的数据库可以有多个副本,并分发到其他节点上。这样在某个数据节点上丢失的数据,可以在其他数据节点上找到并恢复。容错性得以提升。

通过这个案例的比喻,也可以很容易地理解HDFS分布式文件系统一个重要的运用场景,就是与第2章中介绍的数据收集相互集成,保存互联网和大型企业内部每天产生的海量数据内容。理解了这些基本的概念,我们就可以画出图3-2来展示HDFS的工作原理了。

图3-2 类似仓储系统的HDFS

不过,在了解了HDFS的大致工作后,我们也会发现,HDFS存在如下几个弱点:

  • 不适合实时性很强的数据访问。试想一下,还是将不同类型的水源分散在不同的仓库存储,而现在有一款神秘的饮料,其制作工艺极其复杂,需要多种类型的净水作为原材料。因此,必须要到多个仓库取货,最后才能组装生产,那么Hadoop公司是不是很累?就是说,对于一个应用的查询,其对应的数据通常是分散在HDFS系统中的不同数据节点上的。为了获取全部的数据,需要访问多个节点,并且将不同部分的结果在网络中传输,最后进行合并。可是,网络传输的速度,相对于本机的硬盘和内存读取,都要慢很多,因此就拖累了数据查询的执行过程。
  • 无法高效存储大量小文件。如果Flume公司有一天突发奇想,想恶搞一下Hadoop公司,送水的时候不再用超级大桶,而是用小奶瓶装,那么Hadoop公司的仓库管理部门绝对要跳脚。本来是1万桶水,结果顷刻之间变成了1亿个小奶瓶,还需要跟踪它们都存储在哪些仓库,简直是要将人逼疯。对于HDFS而言,命名节点承担的就是协调和管理工作,如果存在太多的琐碎文件,就意味着有庞大的元数据需要处理,这无疑大大增加了命名节点的负载。命名节点检索的效率会明显下降,最终也会导致整体的处理速度放缓。

此外,HDFS对多用户的写入及文件任意修改的支持也不足。文件并发时的写入者只有1个,而且写操作只能在文件末尾追加新的数据,还不能在文件的任意位置进行插入。但不管怎样,HDFS整体上还是拥有良好的分布式文件系统设计,对Hadoop及其生态体系的流行起到了关键的作用。