Hadoop + Spark生态系统操作与实战指南
上QQ阅读APP看书,第一时间看更新

3.2 HDFS原理介绍

3.2.1 HDFS是什么

Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。它和现有的分布式文件系统有很多共同点,同时,它和其他的分布式文件系统的区别也是很明显的。

• HDFS是一个高度容错性的系统,适合部署在廉价的机器上。

• HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。

• HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。

• HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。

• HDFS是Apache Hadoop Core项目的一部分。

HDFS有着高容错性(fault-tolerant)的特点,并且设计用来部署在低廉的(low-cost)硬件上,而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求(requirements),这样可以实现流的形式访问(streaming access)文件系统中的数据。

3.2.2 HDFS架构介绍

1. HDFS架构

HDFS架构如图3-4所示。

图3-4 HDFS架构

从图中可以看出来,HDFS中三个重要的组件是:

• NameNode

• DataNode

• Sencondary NameNode

2.数据存储细节

HDFS的block存储如图3-5所示。

图3-5 HDFS的block存储

3. NameNode

NameNode的目录结构:

    ${dfs.name.dir}/current /VERSION
                                                      /edits
                                                      /fsimage
                                                      /fstime

dfs.name.dir是hdfs-site.xml里配置的若干个目录组成的列表。

NameNode上保存着HDFS的名字空间。对于任何对文件系统元数据产生修改的操作,NameNode都会使用一种称为EditLog的事务日志记录下来。例如,在HDFS中创建一个文件,NameNode就会在Editlog中插入一条记录来表示;同样地,修改文件的副本系数也将往Editlog插入一条记录。NameNode在本地操作系统的文件系统中存储这个Editlog。整个文件系统的名字空间,包括数据块到文件的映射、文件的属性等,都存储在一个称为fsimage的文件中,这个文件也是放在NameNode所在的本地文件系统上。

NameNode在内存中保存着整个文件系统的名字空间和文件数据块映射(Blockmap)的映像。这个关键的元数据结构设计得很紧凑,因而一个有4GB内存的NameNode足够支撑大量的文件和目录。当NameNode启动时,它从硬盘中读取Editlog和fsimage,将所有Editlog中的事务作用在内存中的fsimage上,并将这个新版本的fsimage从内存中保存到本地磁盘上,然后删除旧的Editlog,因为这个旧的Editlog的事务都已经作用在fsimage上了。这个过程称为一个检查点(checkpoint)。在当前实现中,检查点只发生在NameNode启动时,在不久的将来将实现支持周期性的检查点。

4. HDFS NameSpace

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

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

5. DataNode

DataNode将HDFS数据以文件的形式存储在本地的文件系统中,它并不知道有关HDFS文件的信息。它把每个HDFS数据块存储在本地文件系统的一个单独的文件中。DataNode并不在同一个目录创建所有的文件,实际上,它用试探的方法来确定每个目录的最佳文件数目,并且在适当的时候创建子目录。在同一个目录中创建所有的本地文件并不是最优的选择,这是因为本地文件系统可能无法高效地在单个目录中支持大量的文件。

当一个DataNode启动时,它会扫描本地文件系统,产生一个这些本地文件对应的所有HDFS数据块的列表,然后作为报告发送到NameNode,这个报告就是块状态报告。

6. Secondary NameNode

Secondary NameNode定期合并fsimage和edits日志,将edits日志文件大小控制在一个限度下。Secondary NameNode执行步骤如图3-6所示。

图3-6 Secondary NameNode执行步骤

7. Secondary NameNode处理流程

(1)NameNode响应Secondary NameNode请求,将edit log推送给Secondary NameNode,开始重新写一个新的edit log。

(2)Secondary NameNode收到来自NameNode的fsimage文件和edit log。

(3)Secondary NameNode将fsimage加载到内存,应用edit log,并生成一个新的fsimage文件。

(4)Secondary NameNode将新的fsimage推送给NameNode。

(5)NameNode用新的fsimage取代旧的fsimage,在fstime文件中记下检查点发生的时间。

8. HDFS通信协议

所有的HDFS通信协议都是构建在TCP/IP协议上。客户端通过一个可配置的端口连接到NameNode,通过ClientProtocol与NameNode交互。而DataNode是使用DataNodeProtocol与NameNode交互。在设计上,DataNode通过周期性地向NameNode发送心跳和数据块来保持和NameNode的通信,数据块报告的信息包括数据块的属性(即数据块属于哪个文件)、数据块ID、修改时间等,NameNode的DataNode和数据块的映射关系就是通过系统启动时DataNode的数据块报告建立的。从ClientProtocol和DataNodeProtocol抽象出一个远程过程调用(RPC),在设计上,NameNode不会主动发起RPC,而是响应来自客户端和DataNode的RPC请求。