Hadoop分布式文件系统的要点总结
0 引言
Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。它和现有的分布式文件系统有很多共同点。但同时,它和其他的分布式文件系统的区别也是很明显的。HDFS是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。HDFS是Apache Hadoop Core项目的一部分。
1 介绍
HDFS将文件系统元数据(File System Metadata)和应用数据(Application Data)分离存放。与其他种类的分布式文件系统类似,例如PVFS[CIRT00], Lustre2, 以及GFS[GGL03],HDFS将元数据存放在专用服务器上,该服务器称为“NameNode”(名称节点);应用数据被存放在其他的服务器上,这些服务器称为“DataNode”(数据节点)。在该分布式系统中,各个服务器之间均通过网络连接,确保节点之间可以通过基于TCP族的协议进行相互通信。HDFS不像Lustre或者PVFS,它并不依赖于数据保护机制(例如RAID)来确保数据的稳定性,而是像GFS那样,在多个DataNode节点上保存数据的多个副本,以此来确保数据的稳定。采用这样的策略,其好处不仅仅在于数据安全方面,在数据传输带宽方面,由于一个数据有多个副本,因此可以通过多线程访问倍速提高带宽(就像迅雷下载的原理一样——译者注),并且采用此种方式还可以提高从较近的服务器节点上获取数据的几率。
2 架构
分离元数据和数据:NameNode和DataNode
存储到文件系统中的每个文件都有相关联的元数据。元数据包括了文件名、i节点(inode)数、数据块位置等,而数据则是文件的实际内容。
在传统的文件系统里,因为文件系统不会跨越多台机器,元数据和数据存储在同一台机器上。
为了构建一个分布式文件系统,让客户端在这种系统中使用简单,并且不需要知道其他客户端的活动,那么元数据需要在客户端以外维护。HDFS的设计理念是拿出一台或多台机器来保存元数据,并让剩下的机器来保存文件的内容。
NameNode和DataNode是HDFS的两个主要组件。
其中,元数据存储在NameNode上,而数据存储在DataNode的集群上。
NameNode不仅要管理存储在HDFS上内容的元数据,而且要记录一些事情,比如哪些节点是集群的一部分,某个文件有几份副本等。它还要决定当集群的节点宕机或者数据副本丢失的时候系统需要做什么。
存储在HDFS上的每份数据块有多份副本(replica)保存在不同的服务器上。在本质上,NameNode是HDFS的Master(主服务器),DataNode是Slave(从服务器)。
2.1 NameNode
HDFS命名空间采用层次化(树状)的结构存放文件和目录。
文件和目录用NameNode上的inodes表示。Inode记录了权限,修改和访问时间,命名空间,磁盘容量等属性。
文件内容会被分成不同的“大块”(典型分块策略是每块128M,不过用户可以对每个文件的分块大小进行选择)。NameNode负责维护命名空间树以及与DataNode上文件数据分块的映射关系。目前采用的设计结构是,每一个集群只有一个NameNode,一个NameNode可以对应多个DataNode以及成千上万的HDFS客户端。一个DataNode可以同步执行多个应用任务。
补充:文件系统的名字空间 (namespace)
HDFS支持传统的层次型文件组织结构。用户或者应用程序可以创建目录,然后将文件保存在这些目录里。文件系统名字空间的层次结构和大多数现有的文件系统类似:用户可以创建、删除、移动或重命名文件。当前,HDFS不支持用户磁盘配额和访问权限控制,也不支持硬链接和软链接。但是HDFS架构并不妨碍实现这些特性。
Namenode负责维护文件系统的名字空间,任何对文件系统名字空间或属性的修改都将被Namenode记录下来。应用程序可以设置HDFS保存的文件的副本数目。文件副本的数目称为文件的副本系数,这个信息也是由Namenode保存的。
2.2 DataNode
数据节点负责存储和提取数据块Block,读写请求可能来自NameNode,也可能直接来自客户端。数据节点周期性向Namenode汇报自己节点上所存储的Block相关信息(也就是心跳信号,下面会说到)。
2.3 块报告
在启动过程中,每个DataNode通过“握手”的方式与另外一个NameNode节点连接。之所以采用“握手”方式,是为了验证DataNode的命名空间ID以及软件的版本号。如果一个节点的ID或者版本号不匹配,那么DataNode节点就会自动关闭。
“握手”之后,DataNode被注册到NameNode。存储ID在DataNode首次注册到NameNode时即被分配,一旦分配后便无法更改。
DataNode采用发送“块报告”(block report)的形式,向NameNode标识其所包含的块副本。块报告包含了块ID,生成时间戳,以及每个块副本的长度等等。 首个块报告会在DataNode注册后立即发送。随后的块报告会每小时发送一次,以确保NameNode能够知道集群中块副本的最新情况。
2.4 心跳报告
在正常情况下,DataNode向NameNode发送“心跳信号”,以确认DataNode运行正常,以及其所包含的块数据可用。默认的“心跳信号”的时间间隔是3秒。如果NameNode长达10分钟没有接受到来自于DataNode的心跳信号,那么久会认为为该DataNode节点已经失效,其所包含的块(block)已经无法使用。
当DataNode失效时,接下来NameNode就会计划在其他的DataNode上创建新的块数据。
NameNode不能直接向DataNode发送请求。它只通过回复心跳信号的方式来向DataNode发送指令。指令的内容包括,将块移到其他节点,移除本地块副本,重新注册和发送即时块报告,关闭当前节点等等。
这些命令对于维护整个系统的完整性来说非常关键,因此即使是在超大集群上,保持心跳信号的频率也是至关重要的。NameNode每秒能够处理上千条心跳信号,并且不影响到NameNode的其他正常操作。
2.5 HDFS客户端
用户应用程序通过HDFS客户端连接到HDFS文件系统,通过库文件可导出HDFS文件系统的接口。
像很多传统的文件系统一样,HDFS支持文件的读、写和删除操作,还支持对目录的创建和删除操作。用户通过带命名空间的路径对文件和目录进行引用。用户程序不需要知道文件系统的元数据和具体存储在哪个服务器上,也不需要关心一个块有多少个副本。
客户端向HDFS写文件的流程
当一个应用程序读一个文件的时候,HDFS客户端首先向NameNode索要包含该文件的文件块的DataNode节点的列表。该列表会按照网络拓扑距离的远近进行排序。然后客户端会直接与相应的DataNode节点进行联系,要求传输所需的文件块。当客户端写一个文件的时候,它会首先要求NameNode选择一个DataNode,该DataNode需要包含所写入的文件的首个文件块。接下来,客户端会搭建一个从节点到节点的通信管道,用以进行数据传输。当第一个块被写入后,客户端会申新的DataNode,用以写入下一个块。此时,新的通信管线建立,客户端会通过管线写入更多的数据。每个文件块所写入的DataNode节点也许会完全不同。客户端,NameNode和DataNode之间的关系如图所示。
3 具体操作流程
3.1 HDFS写过程
NameNode负责管理存储在HDFS上所有文件的元数据,它会确认客户端的请求,并记录下文件的名字和存储这个文件的DataNode集合。它把该信息存储在内存中的文件分配表里。
例如,客户端发送一个请求给NameNode,说它要将“1.log”文件写入到HDFS。那么,其执行流程如图1所示。具体为:
第一步:客户端发消息给NameNode,说要将“1.log”文件写入。(如图1中的①)
第二步:NameNode发消息给客户端,叫客户端写到DataNode A、B和D,并直接联系DataNode B。(如图1中的②)
第三步:客户端发消息给DataNode B,叫它保存一份“1.log”文件,并且发送一份副本给DataNode A和DataNode D。(如图1中的③)
第四步:DataNode B发消息给DataNode A,叫它保存一份“1.log”文件,并且发送一份副本给DataNode D。(如图1中的④)
第五步:DataNode A发消息给DataNode D,叫它保存一份“1.log”文件。(如图1中的⑤)
第六步:DataNode D发确认消息给DataNode A。(如图1中的⑤)
第七步:DataNode A发确认消息给DataNode B。(如图1中的④)
第八步:DataNode B发确认消息给客户端,表示写入完成。(如图1中的⑥)
图1 HDFS写过程示意图
在分布式文件系统的设计中,挑战之一是如何确保数据的一致性。对于HDFS来说,直到所有要保存数据的DataNodes确认它们都有文件的副本时,数据才被认为写入完成。因此,数据一致性是在写的阶段完成的。一个客户端无论选择从哪个DataNode读取,都将得到相同的数据。
3.2 HDFS读过程
为了理解读的过程,可以认为一个文件是由存储在DataNode上的数据块组成的。客户端查看之前写入的内容的执行流程如图2所示,具体步骤为:
第一步:客户端询问NameNode它应该从哪里读取文件。(如图2中的①)
第二步:NameNode发送数据块的信息给客户端。(数据块信息包含了保存着文件副本的DataNode的IP地址,以及DataNode在本地硬盘查找数据块所需要的数据块ID。) (如图2中的②)
第三步:客户端检查数据块信息,联系相关的DataNode,请求数据块。(如图2中的③)
第四步:DataNode返回文件内容给客户端,然后关闭连接,完成读操作。(如图2中的④)
图2 HDFS读过程示意图
客户端并行从不同的DataNode中获取一个文件的数据块,然后联结这些数据块,拼成完整的文件。
未完……
本文参考了:
1.http://blog.csdn.net/zhouzhaoxiong1227/article/details/46906307
2.http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_design.html
3.http://blog.csdn.net/kingstar158/article/details/18614793