Hadoop分布式文件系统(HDFS)是一个运行在普通商用服务器上的分布式文件系统。他和很多的分布式文件系统类似,但是也有很显著的不同。HDFS是一个高容错并且可以部署在廉价机器上运行的系统。HDFS适用于大型系统提供了应用数据的高吞吐量支持。HDFS降低了流式访问文件系统数据的POSIX协议相关的一些要求。HDFS一开始是设计成为Apache Nutch网络搜索引擎项目的基础架构. 而HDFS也是Apache Hadoop Core项目的部分. 详情参见项目链接http://hadoop.apache.org。
硬件错误时有发生,并非意外。一个HDFS实例可能包含了成千上万台服务器, 它们各自存储了该文件系统的一部分数据。可以说,分布式系统中可能连接了数量极多的节点,而每个节点由于不同的可能性发生故障,这意味着在HDFS中总是有些节点不能正常提供服务。因此,自动和快速的检查并修复故障,是设计HDFS架构的一个核心目标.
运行于HDFS之上的应用会流式访问它们的数据集。They are not general purpose applications that typically run on general purpose file systems. HDFS被设计为更适合批处理数据,而不是与用户有频繁交互的场景. 其侧重点为数据访问的高吞吐量,而不是低延迟性。 POSIX规定硬件方面导到一定要求,而以HDFS为存储目标的应用并不会用到这些资源;因此POSIX中一些关键的语义已经被更改,以提高数据吞吐率。
运行在HDFS之上的应用一般都拥有大量数据. 一个HDFS文件通常大小在GB到TB之间。因此,HDFS理应很好地支持大文件. 它在一个集群上应该能提供相当高的数据带宽,并能能将数据拓展到数百个节点. 在一个应用实例中. 它要支持数以百万计的数据文件。
HDFS应用要求文件访问为write-once-read-many模型. 一个文件被创建,写入并关闭后,就不应该再作修改。这个原则简化了文件的数据一致性问题,并使得数据能被高速率地访问。一个Map/Reduce或者web crawler应用就很适合这种模型. 现在已有计划在将来实现追加数据到文件中的功能。
一个应用所需的计算,数据离应用越近该计算就越高效;对于大数据集的应用场景来说更是如此. 这最大程度地减少了网络开销并增加了系统整体的数据吞吐量。这个理念就是,将计算模块迁移到数据所在的节点中,会比将数据传输到应用所在的节点上的性能显然要好得多。而HDFS也提供了将应用本身移动到相关数据所在节点上的接口。
HDFS可以轻易在不同平台间做到移植。这有利于HDFS成为一个处理拥有大数据的应用的首选平台,并被广泛使用。
NameNode和DataNode都是为了设计成运行在商业机器上的软件体。这些机器一般都安装了GNU/Linux操作系统. HDFS采用Java实现; 任何装有Java运行环境的机器都可以配置为NameNode或者DataNode。采用高可移植性的Java语言意味着HDFS可以部署在绝大部分类型的机器上。一种典型的集群部署为:专门用一台机器作为NameNode来管理相关的资源和任务调度;其他所有的机器作为DataNode来执行相关的计算及存储任务。HDFS架构并不排除在同一台机器上部署了多个DataNode,但这样的场景并不多见。
只存在一个NameNode实例的模型很大程度简化了系统的架构。而NameNode则是一个仲裁者并维护了所有的HDFS元数据,通过这样的方式使得用户数据的传输不用经过NameNode。
HDFS支持传统的分层文件组织。用户或者应用可以在这些文件目录下创建子目录并存储文件数据。HDFS命名空间层次结构与现有大多数的文件系统相似: 用户可以创建,删除,移动或重命名文件。HDFS目前还不支持用户对磁盘配额及修改访问权限,也不支持硬链接或软链接。然而并不排除将来加入这些特性的可能。
我们知道NameNode是用来维护文件系统命名空间的,它会记录对命名空间及其属性所有的改动。用户可以在NameNode中指定数据文件有多少份备份,文件的备份数量称为replication。
HDFS要求在一个大集群中对跨节点的数据存储有高可靠性。文件会被存储为顺序的block,除了最后一个block其他的size都相等。这些block通过冗余备份来增强容错性,而备份数量和size都可以在配置文件中指定。创建了完整的冗余文件后,该文件不用担心同步的问题,因为HDFS是一次写入模式,并且在任何时候只有一个进程在写。
NameNode对block的复制有绝对的决策权。它会从各节点中周期性地接收Heartbeat信号和Blockreport信息。Heartbeat表明该DataNode还可以正常工作,而Blockreport则包含了一个该节点所有block的列表。
由于HDFS的可靠性和高性能,副本位置的选择是严格的。经过优化的副本放置可以让HDFS区别于其他分布式文件系统,而该项特性需要不断的调优和实践。副本放置采用机架感知策略目的是为了提高数据的可靠性,可用性和网络带宽利用率。 采用这种策略的短期目标是在生产系统上进行验证,同时了解更多关于它的行为,并建立一系列测试来研究更复杂的策略。
许多HDFS实例通常是运行在由跨机架组成的计算机集群中,而不同机架上的两个节点一般要通过交换机来进行通信。通常来说,同一机架上的机器的网络带宽要比不同机架的大很多。
NameNode通过 Hadoop Rack Awareness所阐述的过程来决定DataNode所属的rack ID。一个简单的但未经优化的策略是将副本放到单独的机架上。这样可以避免由于整台机架崩溃引起的数据丢失,同时在进行读数据时利用到多个机架的带宽。这个策略甚至可以将副本分布在不同机器上以实现均衡负载。然而,这也增加了读操作的开销,因为写意味着需要将block数据传输到不同的机架上。
一般来副本数量为3时,HDFS的策略为将一份副本放在本机架的与正本相同的节点上,另一份放在同一机架的不同节点上,最后一份会放在另一机架的节点上。这种策略会减少机架间写操作的通讯开销,从而提高了写的性能。整个机架崩溃要比节点发生故障的概率小的多,因此该策略不会影响数据的可靠性和稳定性。另外它也降低了读数据时的网络开销,因为一个block数据是放置在两个独立的机架上而不是三个。使用这种策略,一个文件的副本并不均匀地分布在不同的机架:三分之一的副本在同一个节点上,三分之二在同一个机架上,剩下三分之一均匀地分布在其余的机架。不需要通过数据可靠性和读性能的折中调优,写性能也得到了提高。
上述描述的作为默认配置的副本防止策略正在紧张开发中。
为了最小化集群整体的网络带宽开销及读延时,HDFS尝试让发起读数据请求的客户端能从离他最近的一份副本获取数据。如果在发起读请求的client同一机架上有对应的副本,该副本首先会被HDFS用来完成数据的读取。如果副本跨越了HDFS的多个数据中心,存储于本地数据中心的副本会优先于远程副本来作为数据的访问源
集群启动期间,NameNode节点会进入一个成为安全模式(Safemode)的特殊状态。这种状态下不会做数据的备份,而NameNode会从DataNodes接收倒Heartbeat和Blockreport信息。一个Blockreport包含了该DataNode所存储的block列表。每个block指定了一个最少副本数量值。当数据block副本的最小序号通过NameNode核对时,我们认为该block是能安全复制的。在经过NameNode核对数据block的备份配置完成后(另外等待30秒),NameNode退出Safemode状态。然后NameNode会判断并列出副本数仍然少于配置要求的份数的block列表,如果列表不为空,那么它就会将这些block拷贝到其他DataNode.
HDFS的命名空间数据保存在NameNode中。NameNode使用了名为EditLog的事务日志来持续记录了文件系统元数据所发生的每一个变化。例如,在HDFS中创建新文件时,NameNode会往EditLog插入一条记录来说明此操作。同样地,修改文件的副本系数时也会在EditLog记录这样的操作。NameNode将EditLog存储在本地操作系统的文件系统的一个文件中。 整个文件系统的命名空间,包括block到file和file system property之间的映射关系, 保存在一个成为FsImage的文件中。此FsImage也是作为一个文件形式存储在NameNode本地文件系统中。
NameNode在内存中保存了一份整个文件系统命名空间和文件Blockmap的镜像。这份重要的元数据项是被压缩保存的,因此一个拥有4GB RAM的NameNode可以支持大量的文件和目录信息。NameNode启动后,它会从磁盘中读取FsImage及EditLog,应用EditLog中所有的事务到存在于内存中的FsImage文件对象,然后将版本较新的这个FsImage文件写入磁盘,之后EditLog就可以被删除了,因为所有的事务已经被持久化到FsImage中。该过程称为checkpoint。当前的实现机制为:一个checkpoint只发生在NameNode启动的时候;将来会逐渐支持周期性的checkpoint过程。
所有HDFS的通信协议都基于TCP/IP协议,客户端会与NameNode机器上的TCP端口建立连接,并通过ClientProtocol协议与NameNode进行会话。而DataNode节点则通过DataNode Protocol与NameNode进行通信。远程过程调用(RPC)同时封装了Client Protocol和DataNode Protocol。而NameNode从不启动任何RPC,相反它会响应来自DataNode或客户端的RPC。
HDFS的首要目标是即使出现故障时仍然可以安全地存储数据。三种故障的类型可以概括为NameNode故障,DataNode故障和网络中断。
每个DataNode会定期向NameNode发送一个心跳信息。如果一部分DataNode与NameNode断开了连接,NameNode会根据心跳信息来觉察到。NameNode会将最近没有发送心跳信息的DataNode标记为dead状态,并且不会再像它们发送任何的IO请求。一个节点被标记为dead,此时所有它那里注册过的任何信息对HDFS来说都不起作用了,这也引起了部分block的拷贝数量少于指定值。NameNode会不断跟踪需要备份的block并且启动复制。必须进行重新复制的理由是:一个DataNode可能因为故障而不可用, 拷贝过程可能失败, DataNode上的磁盘可能坏掉, 或者副本数量会被增加。
HDFS架构会兼容数据重新均衡的策略。其设想是当节点 A的剩余空间明显低于某一阈值时,HDFS会自动选择从其他节点移动数据到节点A;当对某个特定文件有紧急高优先级的需求时, HDFS将会动态增加文件拷贝及重新均衡数据。但目前这些设想还没有实现。
数据完整性
存储在某个DataNode上的数据很可能会被损坏,可能是由于存储设备故障,网络故障或者软件漏洞所致。HDFS客户端应用实现了对文件内容的校验和。客户端创建HDFS文件时,它会计算每个文件的每个block的校验和并在相同的命名空间下的单独隐藏的文件中保存这些值。当客户端接收文件数据时,会首先验证校验和。如果校验失败,客户端会向其他拥有同样复本的DataNode重新获取数据。
元数据磁盘故障
快照(Snapshot)支持在某个时间点拷贝并保存一份数据。一种应用场景是快照用于将HDFS实例回滚到故障之前某个合适的状态(HDFS目前不支持Snapshot,但会在以后的版本中实现)。
数据组织
数据块
HDFS用于存储大文件,兼容HDFS的应用都是那些需要处理大数据集的应用。这些应用一般会只一次写入数据,但会读取多次并要求满足流式读取。HDFS支持文件的write-once-read-many原则。HDFS中典型的块大小为64 MB,因此一个文件往往会被切成64MB的大量的块(通常这些快会保存在不同的节点上)。
Staging
客户端创建文件的请求其实并没有立即发送给Namenode,事实上初始时HDFS客户端会先将文件数据缓存到本地的一个临时文件。应用程序的写操作被重定向到这个临时文件,这个操作对外是透明的。当这个临时文件的数据量超过block大小时,客户端才会通知Namenode。Namenode将文件名插入文件系统的层次结构中,并且分配一个数据块给它,然后向客户端返回Datanode的标识符和目标数据块。接着客户端将这块数据从本地临时文件flush到指定的Datanode。当文件关闭时,在临时文件中还没有上传的数据也会传输到指定的Datanode上;然后客户端通知Namenode该文件已关闭。此时Namenode才将文件创建操作持久化到日志文件里。如果Namenode在文件关闭前宕机,则该文件将丢失。
以上方法是对在HDFS上运行的目标应用进行认真考虑后才采用的。这些应用规定要以流式写入文件,如果不采用客户端缓存,网络速度和网络堵塞会对吞吐率造成较大的影响。这种方法并不是首创的,早期的文件系统如AFS,就是用客户端缓存来提高性能。为了有更高的数据上传效率,已经放松了POSIX标准。
流水线复制
HDFS向应用提供了多种访问方式。用户可以通过原生的 FileSystem Java API接口来访问,也可以通过C语言的封装API访问,甚至还可以通过浏览器的方式访问HDFS中的实例文件。目前正在开发通过WebDAV协议来访问HDFS。
FS Shell
操作 | 命令 |
---|---|
创建目录/foodir | bin/hadoop dfs -mkdir /foodir |
删除目录/foodir | bin/hadoop dfs -rmr /foodir |
查看文件/foodir/myfile.txt的内容 | bin/hadoop dfs -cat /foodir/myfile.txt |
FS shell的目的是为那些需要通过脚本语言来与数据交互的应用。
DFSAdmin
DFSAdmin命令用于管理HDFS集群,只能被HDFS管理员使用。以下是一些操作/命令的示例:
操作 | 命令 |
---|---|
将集群设置为安全模式 | bin/hadoop dfsadmin -safemode enter |
显示DataNode列表 | bin/hadoop dfsadmin -report |
上线或下线DataNode(s) | bin/hadoop dfsadmin -refreshNodes |
一个典型的HDFS安装会在一个可配置的TCP端口开启一个用于展示命名空间的web服务。这使得用户可以浏览HDFS明明空间及查看文件内容。
回收存储空间
文件的删除及恢复