本文固定链接:https://www.askmac.cn/archives/hadoop-architecture.html
本文是官方文档的翻译:http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html
1介绍
HDFS 是一个分布式的文件系统,被设计运行在商业硬件上。它和现有的分布式文件系统有很多相似之处。但是,也于其他的分布式文件系统有显著的差异。HDFS是高度容错的,并且被设计来部署到底成本的硬件上。HDFS提供高吞吐量访问应用程序数据,并适用于那些有很大数据集的应用程序。HDFS放松一些POSIX请求使得流媒体访问文件系统数据。HDFS最初的基础设施构建是为了Apache Nutch搜索引擎项目。HDFS是Apache Hadoop核心的项目部分。该项目的URL是http://hadoop.apache.org/
2 假设和目标
2.1 硬件故障
硬件故障是标准的而不是例外。一个HDFS实例可能包括数百或数千个服务器,每一个存储文件系统的部分数据。事实上,这里有大量的组件,每个组件都有一个不一样的失效概率,意味着HDFS的一些组件总是不能提供功能。因此,故障的快速检测,自动的恢复是HDFS的一个核心构架目标(www.askmac.cn)。
2.2 流数据访问
运行在HDFS中的应用程序需要流媒体来访问他们的数据集。它们不是一般运行于通用文件系统的通用应用程序。HDFS被设计为批处理,而不是由用户交互使用。重点是高吞吐量的数据访问,而不是低延迟的数据访问。POSIX强加的一些需求并不是HDFS的应用程序所需要的。POSIX在一些关键领域中的词义已经被交换,来增加数据吞吐速率。
2.3 大数据集
那些在HDFS上运行的应用程序由大量的数据集。HDFS中一个典型的文件在10亿字节到百万兆字节大小。因此,HDFS被调整支持大文件。它应该提供高聚集数据带宽,并且在一个集群中有数百个节点的规模。它应该支持在一个单一的实例有数以百万计的文件。
2.4简单的一致性模型
HDFS应用重新需要写一次,读多次的访问文件模型。文件一旦被创建,写入,和关闭就不应该被修改。这个假设简化了数据一致性问题,允许高吞吐量的数据访问。一个Map/Reduce应用程序或者一个web爬虫程序完全符合这个模型。在将来,有一个计划是支持对一个文件的追加写(www.askmac.cn)。
2.5 移动计算比移动数据代价更低
一个应用程序的计算请求,如果在执行的时候,其操作的数据在其附近的话,它的效率会很高。特别是当数据集的大小非常大的时候,尤其如此。这最大限度地减少网络拥塞,和提高系统的整体吞吐量。这个假设是,迁移计算到数据的位置,比移动数据到应用程序正在运行的地方更好。HDFS提供了接口给应用程序,来移动它们本身到更靠近数据所在位置。
2.6 跨异构硬件和软件平台的可移植性
HDFS被设计的很容易从一个平台移植到另一个平台。这有利于广泛选择HDFS作为一个大的应用程序的平台。
3 . NameNode 和DataNodes
HDFS有主/从 架构。一个HDFS集群包含一个NameNode,一个主服务器用来管理文件系统命名空间和控制客户端访问文件。除此之外,有一系列的DataNodes,通常在集群中对应一个节点,管理连接到他们运行的节点上的存储。HDFS暴露文件系统命名空间,并允许用户将数据存储在文件中。在内部,一个文件被分成一个或多个数据块,这些块存储在一组DataNodes中。NameNode执行文件系统的命名空间操作,例如打开,关闭和重命名文件和目录。它也决定块和DataNodes的映射关系。DataNodes的职责是为文件系统客户端的读写请求服务。DataNode也执行经过Namenode的指令,进行块创建,删除和复制(www.askmac.cn)。
NameNode和DataNode是被设置在商业机器上运行的软件。这些机器通常运行一个GNU/Linux操作系统。HDFS是由java语句构建的;任意支持JAVA的机器都可以运行NameNode或DataNode软件。高度可移植使用的java语言,意味着HDFS可以部署在广泛的机器上。一个典型的部署是由一个专门的机器只运行NameNode软件。集群中其他的机器每一个实例运行一个DataNode软件。构架并不妨碍在同一个机器上运行多个DataNodes,但是在实际情况下这种场景很少见。
一个集群中单独的NameNode的存在方式,大大简化了系统的构架。NameNode是仲裁员和所有HDFS元数据的资料库。这个系统被设计为这样一种方式,用户数据永远不会流经NameNode。
4. 文件系统的命名空间
HDFS提供一个传统的文件组织层级。一个用户或者一个应用可以创建目录和存储文件在这些目录中。文件系统的命名空间层次结构与大多数其他现有的文件系统相似;可以创建和移除文件,移动文件从一个目录到其他目录,或者重命名一个文件。HDFS尚未实现用户配额或访问权限。HDFS不支持硬链接或软连接。但是,HDFS架构并不妨碍实现这些功能。
NameNode 维护文件系统命名空间。任何文件系统命名空间或其属性的改动,被NameNode记录。应用程序可以指定一个文件应该由HDFS维护副本的数量。文件拷贝的数量被称为该文件的复制因子。此信息由NameNode存储。
5.数据拷贝
HDFS被设计为通过在一个大的集群中的机器,可靠地存储非常大的文件。它将每个文件存储为有序列的块;除最后一个块外,所有的块都是相同大小的。一个文件的块复制用于容错。块大小和复制因子可以为每个文件配置。应用程序可以指定一个文件的副本数。复制因子可以在文件创建时间指定,并且可以在以后更改。在HDFS中的文件只写一次,并且在任何时刻严格地保持一个写操作。
NameNode 做出所有关于复制块的决定。它定期的从集群中的每个DataNodes接收到心跳和块报告。一个心跳的返回表明DataNode运行正常。一个块报告包含一个DataNode上所有块的一个列表(www.askmac.cn)。
5.1 副本布局:第一步原始步骤
副本的位置是HDFS的可靠性和性能的关键。优化副本位置区别HDFS于其他分布式文件系统。这是一个需要大量调整和经验的特性。机架感知的副本放置策略的目的是提高数据的可靠性,可用性和网络带宽利用率。当前执行的副本放置策略是在这个方向上的第一次努力。实施这一政策的短期目标是验证生产系统,了解它的行为,并建立一个测试基础和研究更先进的政策(www.askmac.cn)。
大型HDFS实例运行在计算机集群中,通常会在多个机架中传播。通过交换机在不同的机架的节点之间进行通信。在大多数情况下,同一机架间的网络带宽比不同机架间的网络带宽更大。
NameNode决定 机架ID和每个DataNode的所属。一个简单的,但非最佳的政策是放置副本在唯一的机架上。这可以防止丢失的数据,当整个机架失败时,允许使用带宽从多个机架读取数据。此策略均匀的分布集群中的副本,这使得它很容易对组件故障进行负载平衡。但是,这个策略增加了写的成本,因为一个写需要转移块到多个机架上。
在一般情况下,当复制因子为3时,HDFS的放置政策是将一个副本放置在本地机架的一个节点中,另一个在本地机架上的不同节点上,在不同的机架上的不同的节点上放置最后一个。这个策略减少了机架间写的流量,一般可以提升写性能。机架故障的机会远远小于节点故障;这一政策不会影响数据的可靠性和可用性。但是,它也减少了再读取数据的时候使用的聚合网络带宽,因为一个块放置在2个唯一的机架上,而不是3个。在这个策略下,一个文件的副本并不是均匀的分布在机架上。三分之一的副本是在一个节点上,三分之二的副本是在一个机架上,其他是三分之一均匀地分布在剩余的机架中。这一政策提高了写性能,而不影响数据的可靠性或读取性能(www.askmac.cn)。
当前,这里所描述的默认副本放置策略是一个正在进行中的工作(www.askmac.cn)
5.2 副本选择
为了减少全局的带宽消耗和读取延时,HDFS试图满足读取的时候从最近的一个副本读取。如果在同一个机架上存在一个副本,则该副本是最优选择的,以满足读取请求。如果angg / HDFS集群跨越多个数据中心,那么一个副本在本地数据中心总比任何远程副本优先选择。
5.3 安全模式
在启动时,NameNode进入一个特殊的状态,被称作安全模式。当NameNode是安全模式时,不会发生数据块的复制。NameNode从DataNode接受心跳和块报告消息。一个块报告包含了一个datanode所持有的数据块列表。每个块具有指定的最小副本数。当一个数据块最小限度的副本被namenode检查后,这个快被认为是安全副本。在一个可配置的安全副本数据块比例在NameNode检查完毕后(还可以配置额外30s),NameNode退出安全模式。其然后决定那些仍然有少于指定数量的副本的数据块(如果有的话)的列表。Namenode然后复制这些块到其他的DataNode
6.文件系统元数据的持久性
HDFS的命名空间被NameNode存储。NameNode使用一个叫做Editlog的事务日志,来永久的记录文件系统元数据的每一个更改。例如,在HDFS创建一个文件会导致NameNode在Editlog中插入一条记录来表明这个操作。同样的,改变一个文件的副本因子会导致一个新的记录插入到Editlog。NameNode使用其主机上,本地的文件系统中一个文件来存储Editlog。整个文件系统命名空间,包含块和文件的映射和文件系统属性,被存储在一个称作FsImage的文件中。FsImage也作为一个文件存储在Namenode的本地文件系统中。
NameNode在内存中,保持完整的文件系统命名空间和文件块映射的镜像。这个关键的元数据项被设计的很紧凑,这样一个有4GB内存的NameNode可以支持数量庞大的文件和目录。当NameNode启动时,它从磁盘读取FsImage和EditLog,从Editlog中将所有的事务应该到内存中表示的FSImage,然后将新版本的FsImage刷回磁盘。然后它可以清理掉旧的Editlog,因为它的所有事物已经被应用到了之前的FsImage。这个过程被称作检查点。在当前的实现中,一个检查点只发生在当NameNode启动时。工作是在进步,在不久的将来支持周期性的检查点。
DataNode在其本地文件系统中存储HDFS数据。DataNode不了解HDFS文件。它在本地文件系统中,为每个HDFS数据存储为一个单独的文件。DataNode不会将所有的文件生成到一个目录中。相反,它使用一种试探来确定每个目录的最佳文件数目,并在适当的时候创建子目录。在同一个目录中创建所有本地文件不是最优的,因为本地文件系统可能无法有效地支持,在单个目录中存在大量文件。当一个DataNode启动时,它会扫描其本地文件系统,生成一个所有HDFS数据块对应每个本地文件的列表,然后将这个报告发送给NameNode:这就是块报告(www.askmac.cn)。
7.通信协议
所有的HDFS通信协议都是在TCP/IP顶层的协议。一个客户端用过可配置的TCP端口于NameNode机器建立连接。这个是NameNode的客户端协议。DataNode和NameNode交谈使用DataNode 协议。一个远程过程调用(RPC)包装抽象客户端协议和DataNode协议。安装设计,NameNode没有发起任何RPCs。相反,它只响应DataNodes或者客户端发布的RPC请求。
8.鲁棒性
HDFS主要的目标是可靠地存储数据,即使在出现故障时。常见的故障有三类,NameNode故障,DataNode故障和网络分区。
8.1 数据磁盘故障,心跳和重新复制
每个DataNode定期的发送心跳信息给NameNode。网络分区会导致Datanodes的一个子集与NameNode失去连接。NameNode会发现丢失心跳信息的情况。NameNode会将最近没收到心跳的DataNode标记为死亡,并且不再接受其任何I/O请求。任何在一个死亡Datanode上注册的数据对HDFS来说将不可用。DataNode的死亡还会导致一些快的复制因子低于指定的值。NameNode会不断的跟踪哪些块需要复制,并且在必要的情况下启动复制。导致必要的重新复制出现的原因可能有很多:DataNode可能不可用,一个部分可能损坏。DataNode上的硬盘可能故障,或者一个文件的复制因子被增加(www.askmac.cn)。
8.2 集群再平衡
HDFS架构与数据调整方案兼容,如果在一个DataNode上的空闲空间低于某一阀值,一个方案可能会自动地将数据从一个DataNode移动到另一个。倘若对一个特殊文件有突然的高需求,一个方案可能会动态地在集群中创建额外的副本和重建平衡其他的数据。这些类型的数据再平衡方案尚未实现。
8.3 数据完整性
在从一个DataNode活动一个块时,这个块可能会发生损坏。这种损坏可能是由于存储设备的故障,网络故障,或者软件bug。HDFS客户端软件实现了对HDFS文件内同的校验和检查。当一个客户点创建一个HDFS文件,它会为文件的每个块计算校验和,并且存储这些校验和在同一个HDFS命名空间中的一个单独影藏的文件中。让一个客户端检索文件内容时,它会验证从每个DataNode集群接收到的数据,于存储在相关联校验和文件的校验和匹配。如果不能匹配,那么客户端可以选择,从另一个有这个块副本的DataNode中,检索这个块。
8.4 元数据磁盘故障
FsImage和EditLog是HDFS的中心数据结构。这些文件的一个损坏可以导致HDFS实例不能工作。由于这个原因,NameNode可以被配置支持维护多个FsImage和EditLog的副本。任何对于FsImage或EditLog的更新会同步更新每个FsImage和EditLog。这种同步更新多个FsImage和EditLog的副本,会降低NameNode可以支持的命名空间每秒事务数。但是,这种下降是可以接受的,即使 HDFS的应用程序是非常密集的数据类型,他们不是元数据密集型。当一个NameNode重启时,它会选择最新的一致性的FsImage和EditLog来使用(www.askmac.cn)。
NameNode机器对于一个HDFS集群来说是一个单点故障。如果NameNode集群故障了,必须进行人工干预。当前呢,NameNode软件的自动重启和故障转移到其他机器还不支持(需要其他组件来支持)
8.5 快照
快照支持在一个特别的瞬间存储数据的一个拷贝。使用快照特性可以回滚一个损坏的HDFS实例到先前的已知好的时间点。HDFS当前不支持快照,但是将在未来的版本支持。
9. 数据组织
9.1 数据块
HDFS被设计来支持非常大的文件。这是应用程序兼容HDFS来处理大的数据集。这些应用程序写它们的数据仅一次,但是会读取多次,并且要保证读取时候数据流的速度。HDFS支持在一个文件上写一次,读多次的语义。一个HDFS经典使用的块大小是64MB,因此,一个HDFS文件被安装64MB的块切割,如果可能的话,每一个块都驻留在不同的节点。
9.2暂留
一个客户点创建一个文件的请求不会立即到达NameNode。实际上,最初的HDFS客户端缓存文件数据到一个本地临时文件。应用程序的写操作透明地被重定向到这个临时文件。当本地文件积累数据超过一个HDFS块大小时,客户端联系NameNode。NameNode将文件名插入到文件系统层级中,并且为它分配一个块。NameNode 以DataNode身份回应客户端的请求,并指定数据块目的地。然后客户点将数据块,从本地的临时文件中刷出到指定的DataNode。当一个文件被关闭时,临时文件中其余未刷出的数据被转移到DataNode。然后客户端告诉NameNode,文件被关闭。此时,NameNode提交创建操作到永久存储。如果NameNode在文件关闭之前挂掉,那这个文件就丢了(www.askmac.cn)。
以上的方法,在经过仔细考虑之后,被运行在HDFS上的应用程序所使用。这些应用程序需要流写入文件。如果客户端在没有任何客户端缓存的情况下直接写入远程文件,网络的速度和网络中的拥塞会大大影响吞吐量。这种做法并非没有先例。在早期的分布式文件系统,例如AFS,已经使用了客户端缓存来提高性能。一个POSIX请求已经轻松的实现了上传数据的高性能。
9.3 复制流水线
当一个客户端写入数据到一个HDFS文件时,如前一节所解释的那样,它的数据首先写入到一个本地文件。假设HDFS文件的复制因子为3。当本地文件积累到一个完成用户数据块时,客户端会检索从NameNode给出的DataNode列表。这个列表包含了块副本所属的DataNode。客户端首先将数据块刷入到第一个DataNode。第一个DataNode在很小的部分开始接受数据,将每个部分写入本地的资料库,和传输这些部分到列表中第二个DataNode上。第二个DataNode,依次开始接受每个数据块部分,将每个部分写入本地的资料库,和传输这些部分到第三个DataNode上。最后,第三个DataNdoe写入数据到其本地资料库。因此,一个DataNode可以从之前的管道接收数据,然后传递数据到管道之后的下一个中。因此,数据是流水管道化的,从一个DataNode到下一个(www.askmac.cn)。
10.可访问性
HDFS可以由应用程序以不同的方式访问。HDFS提供了一个 文件系统JAVA API来给应用程序使用(http://hadoop.apache.org/docs/current/api/)。一个C语言包装对这个API来说也是可用的。除此之外,一个HTTP游览器,也可以被用来游览一个HDFS实例的文件。工作进程通过WebDAV协议暴露HDFS。
10.1 FS shell
HDFS允许用户数据以文件和目录的形式来组织。它提供了一个命令行接口,称为FS shell,让用户可以与HDFS中的数据交互。语法和其他shell类似(例如。bash,csh),下面是一些例子:
动作 | 命令 |
创建一个目录/foodir | bin/hadoop dfs -mkdir /foodir |
移除目录/foodir | bin/hadoop fs -rm -R /foodir |
查看文件/foodir/myfile.txt的文本内容 | bin/hadoop dfs -cat /foodir/myfile.txt |
FS shell 的目的是为了支持在和数据交互的时候应用程序需要使用脚本。
10.2 DFSAdmin
DFSAdmin命令集,被用于管理一个HDFS集群。这些命名只能被一个HDFS管理员使用。下面是一些使用例子:
动作 | 命令 |
将集群置为安全模式 | bin/hdfs dfsadmin -safemode enter |
收集DataNodes列表 | bin/hdfs dfsadmin -report |
重新加入或者剔除Datanode | bin/hdfs dfsadmin -refreshNodes |
10.3 游览器接口
一个典型的HDFS安装,会通过可配置的TCP端口保留HDFS 命名空间到一个we服务器上。这允许一个用户通过一个web游览器来导航HDFS命名空间和检查其文件内容。
11 空间的回收利用
11.1 文件删除和取消
当一个文件被一个用户或者一个应用程序删除时,它并不能立即从HDFS中移除,HDFS首先将这个文件重命名到/trash目录中。当这个文件还保存在/trash中时,其可以被迅速恢复。一个文件保持在/trash是可配置时间的。在/trash中的文件过期后,NameNode会从HDFS命名空间中删除文件。这个删除会让分配给这个文件的块重新可用。注意在用户删除后HDFS中相应可用空间增加之间,可能会有一个明显的时间延时。
一个用户可以在删除一个文件后取消它,只要它还维持在/trash目录中。如果一个用户想要取消删除文件,他可以在/trash目录中检索这个文件。/trash目录中只包含那些已删除文件的最新副本。/trash 目录和其他目录一样,但是有特殊的特性:HDFS应用特殊的策略来自动删除这个目录中的文件。当前默认trash 间隔 设置为0(删除文件不会存储到trash中)这个值可以在core-site.xml中的fs.trash.interval配置(www.askmac.cn)
11.2 减少复制因子
当一个文件的复制因子降低时,NameNode选择过剩的副本,可以被删除。下一个心跳会将这些信息传递给DataNode。然后DataNode移除相关的块和释放相关的空间到集群中。再一次地,在完成调用setReplication API和释放空间到集群之间,会有一个时间的延时。
12 参考链接
hadoop API: http://hadoop.apache.org/docs/current/api/
hadoop源代码:http://hadoop.apache.org/version_control.html
Comment