·第3个副本:放置在与第2个副本相同机架的节点上。分布式文件管理系统有很多,如DFS和HDFS,而HDFS适用于一次写入、多次查询的情况.

DFS介绍

由于一台机器的存储容量有限,一旦数据量达到足够的级别,就需要将数据存放在多台机器上,这就是分布式文件系统,又称之为DFS(Distributed FileSystem)。

DFS是HDFS的基础,本节将简单讲解一下什么是DFS及DFS的结构,随后引出Hadoop的核心组件HDFS

分布式文件系统DFS是基于Master/Slave模式,通常一个分布式文件系统提供多个供用户访问的服务器,一般都会提供备份和容错的功能。

分布式文件系统管理的物理资源不一定直接连接在本地节点上,而是通过计算机网络与节点相连,而非文件系统管理的物理存储资源一定直接连在本地节点上。

DFS的结构

分布式文件系统在物理结构上是由计算机集群中的多个节点构成的,如图3.1所示。这些节点分为两类,一类叫“主节点”(Master Node),也被称为“名称节点”(NameNode);另一类叫“从节点”(SlaveNode),也被称为“数据节点”(DataNode)。

dfs fs hadoop 命令 hadoop fs hdfs dfs_HDFS

 

 

 HDFS介绍

前面讲到的DFS是统称的分布式文件系统,在Hadoop中实现的分布式文件系统被称之为HDFS,接下来将会介绍HDFS的基本概念、执行原理及文件的读写流程。

HDFS的概念及体系结构

HDFS是Hadoop自带的分布式文件系统,即Hadoop Distributed File System。HDFS是一个使用Java语言实现的分布式、可横向扩展的文件系统。

HDFS包括一个名称节点(NameNode)和若干个数据节点(DataNode),属于主/从(Master/Slave)关系的结构模型。其中,名称节点负责管理文件系统的命名空间及客户端对文件的访问,也就是中心服务器。

而集群中的数据节点一般是一个节点运行一个数据节点进程,其中每个数据节点上的数据实际上是保存在本地的Linux文件系统中,并在名称节点的统一调动下,负责处理文件系统客户端的读/写请求,或删除、创建和复制数据块等操作。

HDFS的设计

HDFS的设计主要是为了实现存储大量数据、成本低廉和容错率高、数据一致性,以及顺序访问数据这4个目标

1.大数据集

HDFS适合存储大量文件,总存储量可以达到PB/EB,单个文件一般在几百兆。

2.基于廉价硬件,容错率高

Hadoop并不需要运行在昂贵且高可靠的硬件上,其设计运行在商用廉价硬件的集群上,因此对于庞大的集群来说,节点发生故障的几率还是非常高的。HDFS遇到上述故障时被设计成能够继续运行且可以不让用户察觉到明显的中断。

3.流式数据访问(一致性模型)

HDFS的构建思路是这样的:一次写入、多次读取是最高效的访问模式。数据集通常由数据源生成或从数据源复制而来,接着长时间在此数据集上进行各种分析。每次分析都将涉及该数据集的大部分数据甚至全部数据,因此读取整个数据集的时间延迟比读取第一条记录的时间延迟更重要。

4.顺序访问数据

HDFS适用于处理批量数据,而不适合随机定位访问。

HDFS的优点和缺点

1.HDFS的优点·

高容错性:数据自动保存多个副本,副本丢失后自动恢复。

适合批处理:移动计算而非数据,数据位置暴露给计算机框架。·

适合大数据处理:GB、TB,甚至PB级数据,百万规模以上的文件数量,10k+节点。

可构建在廉价机器上:通过副本提高可靠性,提供了容错和恢复机制。

2.HDFS的缺点

·不适合低延时数据访问:寻址时间长,适合读取大文件,低延迟与高吞吐率。

·不适合小文件存取:占用NameNode大量内存,寻找时间超过读取时间。

·并发写入、文件随机修改:一个文件只能有一个写入者,仅支持append(日志),不允许修改文件。

HDFS的执行原理

客户端传入文件读写请求时,NameNode(HDFS的集群管理节点)首先接受客户端的读写服务请求,并根据它保存的Metadata元数据,包括元数据的镜像文件(fsimage和操作日志edits信息)和DataNode(数据存储)通信并进行资源协调,Secondary NameNode进行edits和fsimage的合并,同时DataNode之间进行数据复制。

如果要存储一个大文件,首先要将文件分割成块,分别放到不同的节点,每块文件都有3个副本备份,并且有一个专门记录文件块存放情况的元数据文件以备查询,如图3.2和图3.3所示。

dfs fs hadoop 命令 hadoop fs hdfs dfs_HDFS_02

 

 

 HDFS的核心概念

1.数据块(block)

每个磁盘都有默认的数据块大小,这是磁盘进行数据读/写的最小单位。HDFS也有块的概念,在HDFS 1.x中默认数据块大小为64MB,在HDFS 2.x中默认数据块大小为128MB。与单一磁盘上的文件系统相似,HDFS上的文件也被划分成块大小的多个分块(chunk),作为独立的存储单元。但与面向单一的文件磁盘系统不同的是,HDFS中小于一个块大小的文件不会占据整个块的空间(例如一个1MB的文件存储在一个128MB的块中时,文件只会使用1MB的磁盘空间,而不是128MB)。

2.NameNode

NameNode为HDFS集群的管理节点,一个集群通常只有一台活动的NameNode,它存放了HDFS的元数据且一个集群只有一份元数据。NameNode的主要功能是接受客户端的读写服务,NameNode保存的Metadata信息包括文件ownership、文件的permissions,以及文件包括哪些Block、Block保存在哪个DataNode等信息。这些信息在启动后会加载到内存中。

3.DataNode

DataNode中文件的储存方式是按大小分成若干个Block,存储到不同的节点上,Block大小和副本数通过Client端上传文件时设置,文件上传成功后副本数可以变更,BlockSize不可变更。默认情况下每个Block都有3个副本。

4.SecondaryNameNode

SecondaryNameNode(简称SNN),它的主要工作是帮助NameNode合并edits,减少NameNode启动时间。SNN执行合并时机如下:·根据配置文件设置的时间间隔fs.checkpoint.period,默认3600秒。·根据配置文件设置edits log大小fs.checkpoint.size,规定edits文件的最大值默认是64MB,如图3.4所示。

dfs fs hadoop 命令 hadoop fs hdfs dfs_dfs fs hadoop 命令_03

 

5.元数据

 

 元数据保存在NameNode的内存中,以便快速查询,主要包括fsimage和edits。

·fsimage:元数据镜像文件(保存文件系统的目录树)。

·edits:元数据操作日志(针对目录树的修改操作)被写入共享存储系统中,比如NFS、JournalNode,内存中保存一份最新的元数据镜像(fsimage+edits)。

HDFS读文件流程

(5)当快到达块的末端时,DFSInputStream会关闭与该DataNode的连接,然后寻找下一个块最佳的DataNode。对于存储在HDFS上的文件,我们可以通过客户端发送读文件请求,主要步骤如下:

(1)客户端通过调用FileSystem对象的open()方法打开要读取的文件,对于HDFS来说,这个对象是DistributedFileSystem的一个实例。

(2)DistributedFileSystem通过使用远程过程调用(RPC)来调用NameNode,以确定文件起始块的位置。

(3)对于每个块,NameNode返回到存有该块副本的DataNode地址。此外,这些DataNode根据它们与客户端的距离来排序。如果该客户端本身就是一个DataNode,那么该客户端将会从包含有相应数据块副本的本地DataNode读取数据。DistributedFileSystem类返回一个FSDataInputStream对象给客户端并读取数据,FSDataInputStream转而封装DFSInputStream对象,该对象管理着DataNode和NameNode的I/O。接着,客户端对这个输入流调用read()方法。

(4)存储着文件起始几个块的DataNode地址的DFSInputStream,接着会连接距离最近的文件中第一个块所在的DataNode。通过对数据流的反复调用read()方法,实现将数据从DataNode传输到客户端。

(5)当快到达块的末端时,DFSInputStream会关闭与该DataNode的连接,然后寻找下一个块最佳的DataNode。

(6)当客户端从流中读取数据时,块是按照打开的DFSInputStream与DataNode新建连接的顺序进行读取的。它也会根据需要询问NameNode从而检索下一批数据块的DataNode的位置。一旦客户端完成读取,就对FSDataInputStream调用close()方法,如图3.5所示。

dfs fs hadoop 命令 hadoop fs hdfs dfs_dfs fs hadoop 命令_04

 

 

 HDFS写文件流程

对于存储在HDFS上的文件也可以写入内容,可以通过客户端发送写文件的请求,主要步骤如下:

(1)客户端调用DistributedFileSystem对象的create()方法新建文件。

(2)DistributedFileSystem会对NameNode创建一个RPC调用,在文件系统的命名空间中创建一个新文件,需要注意的是,此刻该文件中还没有相应的数据块。

(3)NameNode通过执行不同的检查来确保这个文件不存在而且客户端有新建该文件的权限。如果这些检查都通过了,NameNode就会为创建新文件写下一条记录;反之,如果文件创建失败,则向客户端抛出一个IOException异常。(4)随后DistributedFileSystem向客户端返回一个FSDataOutputStream对象,这样客户端就可以写入数据了。和读取事件类似,FSDataOutputStream封装一个DFSOutputStream对象,该对象会负责处理DataNode和NameNode之间的通信。在客户端写入数据的时候,DFSOutputStream将它分成一个个的数据包,并且写入内部队列,被称之为“数据队列”(data queue)。

(5)DataStream处理数据队列,它的任务是选出适合用来存储数据副本的一组DataNode,并据此要求NameNode分配新的数据块。这一组DataNode会构成一条管线,DataStream会将数据包流式传输到管线中的第一个DataNode,然后依次存储并发送给下一个DataNode。

(6)DFSOutPutStream也维护着一个内部数据包队列来等待DataNode的收到确认回执,称为“确认队列”(ask queue)。收到管道中所有DataNode确认信息后,该数据包才会从确认队列删除。

(7)客户端完成数据的写入后,会对数据流调用close()方法,如图3.6所示。

dfs fs hadoop 命令 hadoop fs hdfs dfs_客户端_05

Block的副本放置策略

 

 

 

 HDFS中的文件作为独立的存储单元,被划分为块(block)大小的多个分块(chunk),在Hadoop 2.x中默认值为128MB。当HDFS中存储小于一个块大小的文件时不会占据整个块的空间,也就是说,1MB的文件存储时只占用1MB的空间而不是128MB。HDFS的容错性也要求数据自动保存多个副本,副本的放置策略如图3.7所示。

dfs fs hadoop 命令 hadoop fs hdfs dfs_数据_06

 

 

·第1个副本:放置在上传文件的DN;如果是集群外提交,则随机挑选一台磁盘不太满、CPU不太忙的节点。

·第2个副本:放置在与第1个副本不同机架的节点上。 

·第3个副本:放置在与第2个副本相同机架的节点上。

·更多副本:随机节点。

author@nohert