基于Hadoop与Spark的大数据开发实战
上QQ阅读APP看书,第一时间看更新

任务1 HDFS入门

关键步骤如下。

认知文件系统以及HDFS文件系统。

了解HDFS文件系统存储的优缺点。

认识HDFS的基本概念。

掌握HDFS的体系架构。

2.1.1 认识HDFS

1.HDFS产生背景

我们在上一章已经了解到当今世界产生的数据量越来越大,那么与之相对应的需要存储和处理的数据量也就越来越大。我们平时使用的操作系统的存储空间是有限的,根本存储不了那么多的数据,那么是否能把多个操作系统综合成为一个大的操作系统,然后把数据存储在这个大的系统中呢?这种方法其实是可行的,但却不方便管理和维护。因此,迫切需要一种系统来管理分散存储在多台机器上的文件,于是就产生了分布式文件管理系统(Distributed File System,DFS)。

那么到底什么是分布式文件系统?分布式文件系统允许将一个文件通过网络在多台主机上以多副本(提高容错性)的方式进行存储,实际上是通过网络来访问文件,用户和程序看起来就像是访问本地的磁盘一样。

2.HDFS简介

HDFS(Hadoop Distributed File System)是Hadoop项目的核心子项目,用于分布式计算中的数据存储。Hadoop官方给出的描述是:HDFS可以运行在廉价的服务器上,为海量数据存储提供了高容错、高可靠性、高可扩展性、高获得性、高吞吐率等特征。说到HDFS,就不得不提Google的GFS,HDFS就是基于它的开源实现。

Hadoop整合了众多的底层文件系统,如本地文件系统、HDFS文件系统、S3文件系统,并提供了一个文件系统抽象类org.apache.hadoop.fs.File System,对应的具体实现类如表2-1所示。

表2-1 Hadoop的文件系统

Hadoop提供了许多文件系统的接口,用户可以使用URI方案选取合适的文件系统来实现交互。

3.HDFS的优点

(1)处理超大文件。这里的超大文件通常是指MB到TB量级的数据文件,Hadoop并不怕文件大;相反,如果HDFS中存在众多的小文件,那么反而会导致Hadoop集群的性能有所下降。

(2)运行于廉价机器上。Hadoop集群可以部署在普通的廉价机器之上,而无需部署在价格昂贵的小型机上,这可以降低公司的运营成本。但要是运行在廉价的机器上,出现故障该怎么办呢?这就要求HDFS自身要做到高可用、高可靠。

(3)流式地访问数据。HDFS提供一次写入、多次读取的服务。比如你在HDFS上存储了一个要处理的问题,后续可能会有多个作业都要使用到这份数据,那么只需要通过集群来读取前面已经存储好的数据即可。HDFS设计之初是不支持对文件追加内容的,但随着Hadoop社区的发展,现在已支持对已有文件进行内容的追加。

4.HDFS的缺点

(1)不适合低延迟数据访问。HDFS本身是为存储大数据而设计的,如果你在工作中遇到的是低延时的应用请求,那么HDFS不适合。实时性、低延迟的查询使用HBase会是更好的选择,但是HBase中的rowkey设计得是否合适也会决定你的查询性能的高低。

(2)无法高效存储大量小文件。HDFS中的元数据(元数据信息包括:文件和目录自身的属性信息,例如文件名、目录名、父目录信息、文件大小、创建时间、修改时间等,记录与文件内容存储相关的信息,例如文件块情况、副本个数、每个副本存放在哪儿等)存放在Name Node中,所以HDFS所能容纳的文件数目由Name Node的内存大小决定。一旦集群中的小文件过多,会导致Name Node的压力陡增,进而影响到集群的性能。所以可以采用Sequence File等方式对小文件进行合并,或者是使用Name Node Federation的方式来改善。

5.HDFS的设计目标

HDFS的设计目标的详细描述可以参考Hadoop的官方文档:http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/Hdfs Design.html#Introduction。本节只挑选几个重要的设计目标进行讲解。

(1)硬件错误。硬件错误是常态而不是异常。HDFS可能由成百上千个服务器所构成,每个服务器上存储着文件系统的部分数据。事实上构成系统的组件数目是非常巨大的,而且任一个组件都有可能失效,这意味着总有一部分HDFS组件是不工作的。因此错误检测和快速、自动的恢复是HDFS最核心的架构目标。

(2)大规模数据集。运行在HDFS上的应用具有很大的数据集。HDFS上的一个典型文件的大小一般都在GB至TB量级。因此,需要调节HDFS以支持大文件存储。HDFS应该能提供整体较高的数据传输带宽,能在一个集群里扩展到数百个节点。一个单一的HDFS实例应该能支撑数以千万计的文件。

(3)移动计算代价比移动数据代价低。一个作业的计算,离它操作的数据越近就越高效,在数据达到海量级别的时候更是如此。因为这样能降低网络阻塞的影响,提高系统数据的吞吐量。将计算移动到数据附近,比将数据移动到应用附近显然更好。HDFS为应用提供了将计算移动到数据附近的接口。

2.1.2 HDFS基础

HDFS体系结构

1.数据块(Block)

HDFS默认的最基本的存储单位是数据块(Block),默认的块大小(Block Size)是64MB(有些发布版本为128MB)。HDFS中的文件是分成以Block Size为大小的数据块存储的。如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间,文件大小是多大就占用多少存储空间。HDFS与Block的关系如图2.1所示。

图2.1 HDFS与Block的关系

2.元数据节点(Name Node)

Name Node的职责是管理文件系统的命名空间,它将所有的文件和文件夹的元数据保存在一个文件系统树中,如一个文件包括哪些数据块,这些数据块分布在哪些数据节点上,这些信息都要存储下来。

Name Node目录结构如下所示。

${dfs.name.dir}/current/VERSION

   /edits

   /fsimage

   /fstime

目录结构描述如下。

(1)VERSION文件是存放版本信息的文件,它保存了HDFS的版本号。

(2)edits:当文件系统客户端进行写操作时,首先记录在修改日志中,元数据节点在内存中保存了文件系统的元数据信息。在记录了修改日志后,元数据节点则修改内存中的数据结构。每次写操作成功之前,修改日志都会同步到文件系统。

(3)fsimage文件即名字空间文件。

3.数据节点(Data Node)

Data Node是文件系统中真正存储数据的地方,一个文件被拆分成多个Block后,会将这些Block存储在对应的数据节点上。客户端向Name Node发起请求,然后到对应的数据节点上写入或者读出对应的数据Block。

Data Node目录结构如下所示。

${dfs.name.dir}/current/VERSION

 /blk_<id_1>

 /blk_<id_1>.meta

 /blk_<id_2>

 /blk_<id_2>.meta

 /...

 /blk_<id_64>

 /blk_<id_64>.meta

 /subdir0/

 /subdir1/

 /...

 /subdir63/

目录结构描述如下。

(1)blk_<id>保存的是HDFS的数据块,其中保存了具体的二进制数据。

(2)blk_<id>.meta保存的是数据块的属性信息:版本信息、类型信息和校验和。

(3)subdirxx:当一个目录中的数据块达到一定数量的时候,则创建子文件夹来保存数据块及数据块属性信息。

4.从元数据节点(Secondary Name Node)

Secondary Name Node并不是Name Node节点出现问题时的备用节点,它和元数据节点分别负责不同的功能。其主要功能就是周期性地将Name Node的namespace image和edit log合并,以防日志文件过大。合并后的namespace image也在元数据节点保存了一份,以防在Name Node失效的时候进行恢复。

Secondary Name Node目录结构如下所示。

${dfs.name.dir}/current/VERSION

   /edits

   /fsimage

   /fstime

   /previous.checkpoint/VERSION

   /edits

   /fsimage

   /fstime

Secondary Name Node用来帮助Name Node将内存中的元数据信息checkpoint到硬盘上。

2.1.3 HDFS架构

1.架构概述

HDFS架构详细描述参见http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/Hdfs Design.html#Name Node_and_Data Nodes。

HDFS采用master/slave架构。一个HDFS集群由一个Name Node和一定数量的Data Node组成。Name Node是一个中心服务器,负责管理文件系统的名字空间(namespace)以及客户端对文件的访问。集群中的Data Node一般是一个节点对应一个,负责管理它所在节点上的存储数据。HDFS暴露了文件系统的名字空间,用户能够以文件的形式在上面存储数据。从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组Data Node上。Name Node执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录,它也负责确定数据块到具体Data Node的映射。Data Node负责处理文件系统客户端的读写请求,在Name Node的统一调度下进行数据块的创建、删除和复制。HDFS架构如图2.2所示。

2.架构组件功能

Name Node和Data Node被设计成可以在普通的商用机器上运行,这些机器一般运行着GNU/Linux操作系统(OS)。由于采用了可移植性极强的Java语言,HDFS可以部署到多种类型的机器上,任何支持Java的机器都可以部署Name Node或Data Node。一个典型的部署场景是一台机器上只运行一个Name Node实例,而集群中的其他机器分别运行一个Data Node实例。这种架构并不排斥在一台机器上运行多个Data Node,只不过这样的情况比较少见。

图2.2 HDFS架构

文件系统的名字空间:HDFS支持传统的层次型文件组织结构。用户或者应用程序可以创建目录,然后将文件保存在这些目录里。文件系统名字空间的层次结构和大多数现有的文件系统类似,用户可以创建、删除、移动或重命名文件。当前,HDFS不支持用户磁盘配额和访问权限控制,也不支持硬链接和软链接。但是HDFS架构并不妨碍对这些特性的实现。

Name Node负责维护文件系统的名字空间,任何对文件系统名字空间或属性的修改都将被Name Node记录下来。应用程序可以设置HDFS保存的文件的副本数目,文件副本的数目称为文件的副本系数,这个信息也是由Name Node保存的。