接上一篇译文:HDFS架构(一)
---------------------------------------------------------
副本放置之第一步
由于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.
File System元数据持久化
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。
数据磁盘故障, 心跳及重新复制
每个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重新获取数据。
元数据磁盘故障
数据块
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 |
回收存储空间
文件的删除及恢复
减少副本系数
HadoopJavaDoc API.
HDFS source code:http://hadoop.apache.org/version_control.html
源文链接:http://hadoop.apache.org/docs/r1.2.1/hdfs_design.html