1、MapReduce与分布式文件系统
前面的讨论中,我们已经得知,Hadoop中实现的MapReduce是一个编程模型和运行框架,它能够通过JobTracker接收客户提交的作业而后将其分割为多个任务后并行运行在多个TaskTracker上。而问题是,这些TaskTracker如何高效获取所要处理的数据?

在传统的高性能集群中,计算节点和存储节点是各自独立的,它们之间通过高速网络完成互联,然而,在面临海量数据处理的问题时,网络必然会成为整个系统的性能瓶颈,这就需要引入超高速的网络如万兆以太网或Infiniband。然而,对大数场景来讲它们属于“奢侈品”,且昂贵的投入并不能带来网络性能的线性提升,因此性价比不高。面对这种问题,MapReduce采取了将计算节点与存储节点合二为一的集群模型,它利用分布式文件系统将数据存储于多个节点上,而后让处理过程在各数据节点本地直接进行,从而极大地降低了数据通过网络传送的需求。不过,这里仍然需要说明的是,MapReduce并非依赖于分布式文件系统,只不过运行在非分布式文件系统的MapReduce的诸多高级特性将无用武之地。
事实上,分布式文件系统并非MapReduce带来的新生事物,只不过,MapReduce站在前人的基础上将分布式文件系统进行了改造以使得它更能够适用于在MapReduce中完成海量数据处理。Google为在他们的MapReduce中实现的分布式文件系统为GFS(Google File System),而Hadoop的实现称作HDFS(Hadoop Distributed File System)。

2、HDFS的设计理念
HDFS的许多设计思想与传统的文件系统(如ext3、XFS等)是类似的,比如文件数据存储于“数据块(block)”中、通过“元数据”将文件名与数据块建立映射关系、文件系统基于目录实现树状组织结构、通过元数据保存文件权限及时间戳等。
但二者也有不同之处,比如传统文件系统实现为系统内核(尤其是Linux系统)中内核模块,可通过用户空间的相关工具进行管理操作,并能够在挂载后供用户使用;但HDFS是一种“用户空间文件系统”,其文件系统代码运行于内核之外并以用户空间进程的形式存在,故不需要在VFS(Virtual FileSystem)注册后向用户空间输出,也不能挂载使用。同时,HDFS还是一个分布式文件系统,这意味着其工作于集群模式中,数据块分布存储于各“存储节点(DataNode)”上,存储空间的整体大小为所有存储节点贡献出的空间之和,但元数据存储于集群中一个称之为“名称节点(NameNode)”专用的节点上。
但二者还有着更进一步的联系。HDFS是用户空间的文件系统,其存储空间是通过数据节点(datanode)上的DataNode进程将本地某文件系统输出为HDFS实现的。这意味着,在配置数据节点时,需要首先准备一个本地文件系统,其可以是某文件系统上一个目录或者是一个独立的已经挂载的文件系统,如/hadoop/storage,而后通过DataNode进程的配置文件将出输出为HDFS即可。当客户端存储文件时,DataNode进程接收进来的数据会存储在/hadoop/storage目录中;不过,需要注意的是,不能通过/hadoop/storage直接访问这些文件。
此外,传统文件系统的“块大小(block size)”通过为1KB、2KB或4KB等,而HDFS的块大小为64MB,且在生产环境中使用时,此块大小通常还会被调整为128MB、256MB甚至是512MB等。HDFS使用块抽象层管理文件,可以实现将分块分为多个逻辑部分后分布于多个存储节点,也能够有效简化存储子系统。而对于存储节点来说,较大的块可以减少磁盘的寻道次数,进而提升I/O性能。
因此,HDFS专为存储大文件而设计,通常以集群模型运行于普通的商业服务器上,基于流式数据访问模型完成数据存取。HDFS将所有文件的元数据存储于名称节点(NameNode)的内存中,能够利用分布式特性高效地管理“大”文件(GB级别甚至更大的文件),对于有着海量小文件的应用场景则会给名称节点的内存空间带去巨大压力并使得其很可能成为系统性能瓶颈。再者,HDFS为MapReduce的计算框架而设计,存储下来数据主要用于后续的处理分析,其访问模型为“一次写入、多次读取”;因此,数据在HDFS中存储完成后,仅能在文件尾部附加新数据,而不能对文件进行修改。另外,HDFS专为了高效地传输大文件进行了优化,其为了完成此目标,在“低延迟”特性上做出了很大让步,因此,其不适用于较小访问延迟的应用。

Hadoop系列之六:分布式文件系统HDFS_第1张图片

图:HDFS架构

3、HDFS的名称节点(NameNode)和数据节点(DataNode)

HDFS集群中节点的工作模型为“master-worker”,其也属于主从架构,包含一个名称节点(master)和多个数据节点(worker)。
名称节点负责管理HDFS的名称空间,即以树状结构组织的目录及文件的元数据信息,这些信息持久存储于名称节点本地磁盘上并保存为名称“空间镜像(namespace image)”和“编辑日志(edit log)”两个文件。名称节点并不存储数据块,它仅需要知道每个文件对应数据块的存储位置,即真正存储了数据块的数据节点。然而,名称节点并不会持久存储数据块所与其存储位置的对应信息,因为这些信息是在HDFS集群启动由名称节点根据各数据节点发来的信息进行重建而来。数据节点的主要任务包括根据名称节点或客户的要求完成存储或读取数据块,并周期性地将其保存的数据块相关信息报告给名称节点。
默认情况下,HDFS会在集群中为每个数据块存储三个副本以确保数据的可靠性、可用性及性能表现。在一个大规模集群中,这三个副本一般会保存至不同机架中的数据节点上以应付两种常见的故障:单数据节点故障和导致某机架上的所有主机离线的网络故障。另外,如前面MapReduce运行模型中所述,为数据块保存多个副本也有利于MapReduce在作业执行过程中透明地处理节点故障等,并为MapReduce中作业协同处理以提升性能提供了现实支撑。名称节点会根据数据节点的周期性报告来检查每个数据块的副本数是否符合要求,低于配置个数要求的将会对其进行补足,而多出的将会被丢弃。

参考文献:

Data-Intensive Text Processing with MapReduce

Hadoop in prictise
Hadoop Operations