浅谈HDFS分布式文件系统

Posted ItStar

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈HDFS分布式文件系统相关的知识,希望对你有一定的参考价值。

浅谈HDFS分布式文件系统

Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。它和现有的分布式文件系统有很多共同点。但同时,它和其他的分布式文件系统的区别也是很明显的。HDFS是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。HDFSApache Hadoop Core项目的一部分。

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

体系结构

HDFS采用了主从(Master/Slave)结构模型,一个HDFS集群是由一个NameNode和若干个DataNode组成的。其中NameNode作为主服务器,管理文件系统的命名空间和客户端对文件的访问操作;集群中的DataNode管理存储的数据。

特点和目标

硬件故障

硬件故障是常态,而不是异常。整个HDFS系统将由数百或数千个存储着文件数据片段的服务器组成。实际上它里面有非常巨大的组成部分,每一个组成部分都很可能出现故障,这就意味着HDFS里的总是有一些部件是失效的,因此,故障的检测和自动快速恢复是HDFS一个很核心的设计目标。

数据访问

运行在HDFS之上的应用程序必须流式地访问它们的数据集,它不是运行在普通文件系统之上的普通程序。HDFS被设计成适合批量处理的,而不是用户交互式的。重点是在数据吞吐量,而不是数据访问的反应时间,POSIX的很多硬性需求对于HDFS应用都是非必须的,去掉POSIX一小部分关键语义可以获得更好的数据吞吐率

大数据集

运行在HDFS之上的程序有很大量的数据集。典型的HDFS文件大小是GBTB的级别。所以,HDFS被调整成支持大文件。它应该提供很高的聚合数据带宽,一个集群中支持数百个节点,一个集群中还应该支持千万级别的文件。

简单一致性模型

大部分的HDFS程序对文件操作需要的是一次写多次读取的操作模式。一个文件一旦创建、写入、关闭之后就不需要修改了。这个假定简单化了数据一致的问题,并使高吞吐量的数据访问变得可能。一个Map-Reduce程序或者网络爬虫程序都可以完美地适合这个模型。

移动计算比移动数据更经济

在靠近计算数据所存储的位置来进行计算是最理想的状态,尤其是在数据集特别巨大的时候。这样消除了网络的拥堵,提高了系统的整体吞吐量。一个假定就是迁移计算到离数据更近的位置比将数据移动到程序运行更近的位置要更好。HDFS提供了接口,来让程序将自己移动到离数据存储更近的位置。

异构软硬件平台间的可移植性

HDFS被设计成可以简便地实现平台间的迁移,这将推动需要大数据集的应用更广泛地采用HDFS作为平台。

名字节点和数据节点

HDFS是一个主从结构,一个HDFS集群是由一个名字节点,它是一个管理文件命名空间和调节客户端访问文件的主服务器,当然还有一些数据节点,通常是一个节点一个机器,它来管理对应节点的存储。HDFS对外开放文件命名空间并允许用户数据以文件形式存储。

内部机制是将一个文件分割成一个或多个块,这些块被存储在一组数据节点中。名字节点用来操作文件命名空间的文件或目录操作,如打开,关闭,重命名等等。它同时确定块与数据节点的映射。数据节点负责来自文件系统客户的读写请求。数据节点同时还要执行块的创建,删除,和来自名字节点的块复制指令。

 

名字节点和数据节点都是运行在普通的机器之上的软件,机器典型的都是GNU/LinuxHDFS是用java编写的,任何支持java的机器都可以运行名字节点或数据节点,利用java语言的超轻便性,很容易将HDFS部署到大范围的机器上。典型的部署是由一个专门的机器来运行名字节点软件,集群中的其他每台机器运行一个数据节点实例。体系结构不排斥在一个机器上运行多个数据节点的实例,但是实际的部署不会有这种情况。

集群中只有一个名字节点极大地简单化了系统的体系结构。名字节点是仲裁者和所有HDFS元数据的仓库,用户的实际数据不经过名字节点。

文件命名空间

HDFS支持传统的继承式的文件组织结构。一个用户或一个程序可以创建目录,存储文件到很多目录之中。文件系统的名字空间层次和其他的文件系统相似。可以创建、移动文件,将文件从一个目录移动到另外一个,或重命名。HDFS还没有实现用户的配额和访问控制。HDFS还不支持硬链接和软链接。然而,HDFS结构不排斥在将来实现这些功能。

名字节点维护文件系统的命名空间,任何文件命名空间的改变和或属性都被名字节点记录。应用程序可以指定文件的副本数,文件的副本数被称作文件的复制因子,这些信息由命名空间来负责存储。

数据复制

HDFS设计成能可靠地在集群中大量机器之间存储大量的文件,它以块序列的形式存储文件。文件中除了最后一个块,其他块都有相同的大小。属于文件的块为了故障容错而被复制。块的大小和复制数是以文件为单位进行配置的,应用可以在文件创建时或者之后修改复制因子。HDFS中的文件是一次写的,并且任何时候都只有一个写操作。

名字节点负责处理所有的块复制相关的决策。它周期性地接受集群中数据节点的心跳和块报告。一个心跳的到达表示这个数据节点是正常的。一个块报告包括该数据节点上所有块的列表。

 

副本位置:第一小步

块副本存放位置的选择严重影响HDFS的可靠性和性能。副本存放位置的优化是HDFS区分于其他分布式文件系统的的特征,这需要精心的调节和大量的经验。机架敏感的副本存放策略是为了提高数据的可靠性,可用性和网络带宽的利用率。副本存放策略的实现是这个方向上比较原始的方式。短期的实现目标是要把这个策略放在生产环境下验证,了解更多它的行为,为以后测试研究更精致的策略打好基础。

HDFS运行在跨越大量机架的集群之上。两个不同机架上的节点是通过交换机实现通信的,在大多数情况下,相同机架上机器间的网络带宽优于在不同机架上的机器。

在开始的时候,每一个数据节点自检它所属的机架id,然后在向名字节点注册的时候告知它的机架idHDFS提供接口以便很容易地挂载检测机架标示的模块。一个简单但不是最优的方式就是将副本放置在不同的机架上,这就防止了机架故障时数据的丢失,并且在读数据的时候可以充分利用不同机架的带宽。这个方式均匀地将复制分散在集群中,这就简单地实现了组建故障时的负载均衡。然而这种方式增加了写的成本,因为写的时候需要跨越多个机架传输文件块。

默认的HDFS block放置策略在最小化写开销和最大化数据可靠性、可用性以及总体读取带宽之间进行了一些折中。一般情况下复制因子为3HDFS的副本放置策略是将第一个副本放在本地节点,将第二个副本放到本地机架上的另外一个节点而将第三个副本放到不同机架上的节点。这种方式减少了机架间的写流量,从而提高了写的性能。机架故障的几率远小于节点故障。这种方式并不影响数据可靠性和可用性的限制,并且它确实减少了读操作的网络聚合带宽,因为文件块仅存在两个不同的机架, 而不是三个。文件的副本不是均匀地分布在机架当中,1/3在同一个节点上,1/3副本在同一个机架上,另外1/3均匀地分布在其他机架上。这种方式提高了写的性能,并且不影响数据的可靠性和读性能。

副本的选择

为了尽量减小全局的带宽消耗读延迟,HDFS尝试返回给一个读操作离它最近的副本。假如在读节点的同一个机架上就有这个副本,就直接读这个,如果HDFS集群是跨越多个数据中心,那么本地数据中心的副本优先于远程的副本。

安全模式

在启动的时候,名字节点进入一个叫做安全模式的特殊状态。安全模式中不允许发生文件块的复制。名字节点接受来自数据节点的心跳和块报告。一个块报告包含数据节点所拥有的数据块的列表。

每一个块有一个特定的最小复制数。当名字节点检查这个块已经大于最小的复制数就被认为是安全地复制了,当达到配置的块安全复制比例时(加上额外的30秒),名字节点就退出安全模式。它将检测数据块的列表,将小于特定复制数的块复制到其他的数据节点。

文件系统的元数据的持久化

HDFS的命名空间是由名字节点来存储的。名字节点使用叫做EditLog事务日志来持久记录每一个对文件系统元数据的改变,如在HDFS中创建一个新的文件,名字节点将会在EditLog中插入一条记录来记录这个改变。类似地,改变文件的复制因子也会向EditLog中插入一条记录。名字节点在本地文件系统中用一个文件来存储这个EditLog。整个文件系统命名空间,包括文件块的映射表和文件系统的配置都存在一个叫FsImage的文件中,FsImage也存放在名字节点的本地文件系统中。

名字节点在内存中保留一个完整的文件系统命名空间和文件块的映射表的镜像。这个元数据被设计成紧凑的,这样4GB内存的名字节点就足以处理非常大的文件数和目录。名字节点启动时,它将从磁盘中读取FsImageEditLog,将EditLog中的所有事务应用到FsImage的仿内存空间,然后将新的FsImage刷新到本地磁盘中,因为事务已经被处理并已经持久化的FsImage中,然后就可以截去旧的EditLog。这个过程叫做检查点。当前实现中,检查点仅在名字节点启动的时候发生,正在支持周期性的检查点。

数据节点将HDFS数据存储到本地的文件系统中。数据节点并不知道HDFS文件的存在,它在本地文件系统中以单独的文件存储每一个HDFS文件的数据块。数据节点不会将所有的数据块文件存放到同一个目录中,而是启发式的检测每一个目录的最优文件数,并在适当的时候创建子目录。在本地同一个目录下创建所有的数据块文件不是最优的,因为本地文件系统可能不支持单个目录下巨额文件的高效操作。当数据节点启动的时候,它将扫描它的本地文件系统,根据本地的文件产生一个所有HDFS数据块的列表并报告给名字节点,这个报告称作块报告。

通信协议

所有的通信协议都是在TCP/IP协议之上构建的。一个客户端和指定TCP配置端口的名字节点建立连接之后,它和名字节点之间通信的协议是Client Protocol。数据节点和名字节点之间通过Datanode Protocol通信。

RPCRemote Procedure Call)抽象地封装了Client ProtocolDataNode Protocol协议。按照设计,名字节点不会主动发起一个RPC,它只是被动地对数据节点和客户端发起的RPC作出反馈。


以上是关于浅谈HDFS分布式文件系统的主要内容,如果未能解决你的问题,请参考以下文章

HDFS—Hadoop底层分布式文件存储系统

技术干货:Hadoop架构的几种部署方式浅谈

浅谈HDFS

浅谈HDFS架构

HDFS 分布式文件系统

02 HDFS 分布式环境实战