您的位置:首页 > 运维架构 > 网站架构

HDFS架构指南(官网)

2015-08-25 17:11 351 查看

简介

Hadoop分布式文件系统(HDFS)是一个设计用来运行在商业机器上的分布式文件系统。它和已存在的分布式文件系统有很多相似之处。当然,和其他分布式文件系统的区别也是非常明显的。HDFS是高容错的,它设计用来部署在低成本的机器上。HDFS提供高吞吐量访问应用数据,对于拥有大数据集的应用非常适合。HDFS最开始是作为ApacheNutch web搜索引擎工程的基本部件开发的。现在,HDFS是Apache Hadoop的子工程。工程URL: http://hadoop.apache.org/hdfs/.

假设和目标

硬件失败

硬件失败并不是什么稀罕事。一个HDFS实体可能包含成百上千的服务机器,每一台都保存文件系统数据的一部分。事实上,因为有大量的组块并且每个组块都有不容忽视的失败概率,这也就意味着HDFS的一些组块总是没工作的。因此,错误检测并快速自动的恢复自然是HDFS的一个核心架构目标。

流数据访问

运行在HDFS上的应用需要流式访问它们的数据集。HDFS与其为被用户交互使用,而不如说是设计用于批处理。这也就算强调HDFS提供的是高吞吐量的数据访问,而不是数据访问的低延时。POSIX强制的很多硬件要求对于针对HDFS的应用来说是不需要的。

大数据集

运行在HDFS上的应用一般都具有大数据集。尺寸上来说,HDFS的一个文件通常是GB到TB级别。这就是说HDFS是用于支持大尺寸文件的。在一个单集群中必须能够提供高的聚合数据带宽和规模上百的节点。必须在一个单实体上支持上千万的文件。

一致性模型

HDFS应用需要为文件提供一个“一次写入,多次读取”的访问模型。一个文件一旦创建、编写和关闭,就不能再改变。这个假定简化了数据一致性问题且保证了高吞吐量的数据访问。一个MapReduce应用或者web抓取应用非常适合这个模型。有计划在今后支持对文件进行添加写入。

“移动计算比移动数据更划算“

一个应用所需的一次计算如果是在它要操作的数据所在的地方附近执行的话,那么它会更加有效。特别是当数据集的尺寸非常大的时候。这最小化了网络拥塞且增加了系统总的吞吐量。这个假定的意思是:将计算移动到数据的附近通常要比将数据移动到应用执行的地方要更好。HDFS为应用提供了将本身移动到靠近数据所在位置的接口。

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

HDFS被设计成很容易从一个平台移植到另一个平台。这样,在大数据集的应用中广泛部署了HDFS。

NameNode 和DataNodes

HDFS有一个 master/slave(主/从)架构。一个HDFS集群包括一个NameNode——一个主服务器负责管理文件系统的命名空间和控制客户端访问文件。此外,还有一定数量的DataNode——通常是集群中的每个节点一个,负责管理它们运行所在的节点上的存储。HDFS开发了一个文件系统命名空间且允许用户数据保存在文件中。在内部,一个文件拆分为一个或跟多的块(block),这些块保存在一个DataNode集上。NameNode执行文件系统命名空间的一些操作,比如打开,关闭和重命名文件和目录。它同样决定着块到DataNode的映射。DataNode负责服务从文件系统的客户端的读写请求。DataNode同样在NameNode的命令的基础上操作块的创建、删除和复制。



NameNode和DataNode是运行在商用机器上的软件分片。这些机器通常运行在GNU/Linux操作系统上。HDFS是用java语言建立的;任何支持Java的机器都能够运行NameNode或DataNode。利用Java语言的高可移植性意味着HDFS能够部署在广泛的机器上。一个通常的部署方式是有一个专门的机器仅仅运行NameNode。集群中的其他的机器每一个会运行一个DataNode实体。架构并不排除在相同的机器上运行多个DataNode,但是在实际部署中很少会出现这些情况。

在一个集群中存在一个单一NameNode很大程度的简化了系统的架构。NameNode是专属的,它会存储所有的HDFS元数据。系统设计成这样的一种方式以至用户数据不会流经NameNode。

文件系统命令空间

HDFS支持传统分层文件组织。一个用户或应用能够建立目录并将文件保存在这些目录中。文件系统命令空间层次和大多数其他存在的文件系统是相似的。你能够创建和删除文件,将文件从一个路径复制到另一个,或者重命名一个文件。HDFS并没有实现用户权限。HDFS不支持硬链接或软连接。但是,HDFS架构不会阻止这些特性。

NameNode管理文件系统命名空间。任何对文件系统命名空间或者它的属性的修改都会被NameNode记录下来。一个应用能够指定保管在HDFS一个文件的副本的数量。一个文件的副本数量叫做文件的复制因子。这些信息是被NameNode保存的。

数据复制

HDFS设计用来可靠地保存一个大的集群中的机器间大量文件。它将每个文件作为一个块序列保存。除了最后那个块外,一个文件的所有块的尺寸大小相同。为了容错,一个文件的块会被复制。对于每个文件,块的尺寸和复制因子都是可配置的。一个应用能够指定一个文件的副本数量。复制因子在文件创建的时候就指定,也可以在后面修改。

所有关于块的复制的事情都由NameNode决定。它会从集群中的每个DataNode接收一个心跳和一个块报告。收到一个心跳说明DataNode工作正常。收到BlockReport 包括一个DataNode上的所有块的一个列表。



副本放置:第一小步

对于HDFS的可靠性和性能,副本的放置是非常关键的。优化副本放置将HDFS和大多数其他分布式文件系统区分开来。这个特性需要很多调试和经验。一个机器感知(不错)的副本放置的目的是为了提高数据可靠性、有效性和网络带宽利用率。在这个方向上的第一个尝试是目前实现的副本放置政策。实施该策略的短期目标是验证它在生产系统上的有用性,了解它的行为,建立一个用来测试和研究更多高级策略的基础。

运行在一个计算机集群上的大型HDFS实体通常覆盖多个机架。不同机架上的两个节点间的通信需要通过交换机。在大多数情况下,相同机架上的机器键的网络带宽要比不同机架上机器间的带宽要更宽。

NameNode决定每个DataNode所需的机架的id。一个简单没有优化的策略是将副本放在特定的机架上。这可以防止当一个整体机架失败时的数据丢失,且当读取数据时允许使用多个机架的带宽。这个策略在集群中平等地分发副本,这样能够在失败的块上很容易实现负载均衡。但是,因为需要一个写来完成将块传递到多个机架,隐藏会增加写的花费。

通常,当复制因子是3时,HDFS放置策略是将一个副本放在本地机架的一个节点上,另一个放置在(远程)机架的一个节点上,最后一个放在相同的(远程)机架的不同节点上。这个策略切割了机架间的写流量,这通常能提高写的性能。机架失败的几率是远远低于节点失败的几率的。这个策略不会影响数据可靠性和有效性保证。但是,当读取数据时,以为一个块仅仅放置在两个特定机架上而不是三个,因此会降低使用的总的带宽。由于该策略,一个文件的副本不会在机架间公平分发。三个中的一个的副本在一个节点,三个的副本中的另一个在一个机架上,剩下那个在剩下的机架上均一分发。这个策略在不损失数据可靠性和读性能的前提下提高了写性能。

副本选择

为了最小化带宽消耗和读取延时,HDFS尝试满足最靠近读取器的一个副本的读取请求。如果在相同的机架上存在一个副本作为读取器节点,那么这个副本就倾向于满足读取请求。如果angg/HDFS集群跨越多个数据中心,那么处于本地数据中心的副本要比任何远程的副本要好。

Safemode(安全模式)

在启动中,NameNode会进入一个叫做安全模式的特定状态。当NameNode处于安全模式状态时不会出现数据块的复制。NameNode从DataNode接收心跳和块报告信息。块报告包含DataNode管理的数据块列表。每个块都有一个指定的最小数量副本。如果数据块的最小数量副本在NameNode节点上检查过,那个这个块就认为是安全复制的。当在NameNode上检查的安全复制数据块完成配置的比例后,再过30秒,NameNode就会退出安全模式状态。然后,NameNode再确定仍然少于指定副本的数据块列表。NameNode进而将这些块复制给其他数据节点。

文件系统元数据的持久性

NameNode保存HDFS命名空间。NameNode使用一个叫做EditLog的交易日志持续的记录文件系统元数据的每一次改变。比如,在HDFS上创建一个新文件时会引发NameNode往EditLog插入一条记录。相似地,改变一个文件的复制因子也会在EditLog中插入一条新纪录。NameNode使用本地服务操作系统上的文件系统的一个文件来存储EditLog.整个文件系统的命名空间,包括块到文件的映射以及系统属性都会存储在叫做FsImage的文件内。FsImage同样作为一个文件保存在NameNode的本地文件系统中。

Namenode在内存中保存着整个文件系统namespace和文件Blockmap的映像。这个关键的元数据设计得很紧凑,因而一个带有4G内存的
Namenode足够支撑海量的文件和目录。当Namenode启动时,它从硬盘中读取Editlog和FsImage,将所有Editlog中的事务作用(apply)在内存中的FsImage
,并将这个新版本的FsImage从内存中flush到硬盘上,然后再truncate这个旧的Editlog,因为这个旧的Editlog的事务都已经作用在FsImage上了。这个过程称为checkpoint。在当前实现中,checkpoint只发生在Namenode启动时,在不久的将来我们将实现支持周期性的checkpoint。

DataNode将HDFS数据保存在本地文件系统的文件中。DataNode并不了解HDFS文件。它将HDFS数据的每个块保存在本地文件系统的一个单独文件中。DataNode不会再相同的目录下创建所有文件。相反,它会使用一种启发式的方式来决定一个目录中的最佳文件数量和合理的建立子目录。只所以在相同的目录下创建所有本地文件不是最佳是因为本地文件系统可能不能在一个单一的目录下有效的支撑大规模的文件。当一个DataNode启动时,它会扫描整个本地文件系统,对这些本地文件产生相应的一个所有HDFS数据块的列表,然后发送报告到Namenode,这个报告就是Blockreport。

通信协议

所有的HDFS通讯协议都是构建在TCP/IP协议上。客户端通过一个可配置的端口连接到Namenode,通过ClientProtocol与
Namenode交互。而Datanode是使用DatanodeProtocol与Namenode交互。从ClientProtocol和
Datanodeprotocol抽象出一个远程调用(RPC),在设计上,Namenode不会主动发起RPC,而是响应来自客户端和
Datanode 的RPC请求。

鲁棒性

HDFS的主要目标是即使存在失败也能可靠的保存数据。三种常见的失败类型为:NameNode失败、DataNode失败和网络割裂。

1、 硬盘数据错误、心跳检测和重新复制

每个DataNode会周期性的发送一个心跳消息给NameNode。网络割裂会导致一部分DataNode与NameNode失去连接。 Namenode通过心跳包的缺失检测到这一情况,并将这些Datanode标记为dead,不会将新的IO请求发给它们。寄存在deadDatanode上的任何数据将不再有效。Datanode的死亡可能引起一些block的副本数目低于指定值,Namenode不断地跟踪需要复制的
block,在任何需要的情况下启动复制。在下列情况可能需要重新复制:某个Datanode节点失效,某个副本遭到损坏,Datanode上的硬盘错误,或者文件的replication因子增大。

2、 集群再均衡

HDFS架构支持数据再均衡方案。如果一个DataNode的自由空间低于某个阈值,方案就会自动将一个DataNode的数据移动到另一个。当对某个文件的请求突然增加,会开启一个方案来创建该文件新的副本,并分布到集群中以满足应用的要求。这些均衡计划目前还没有实现。

3、 数据完整性

从某个Datanode获取的数据块有可能是损坏的,这个损坏可能是由于Datanode的存储设备错误、网络错误或者软件bug造成的。HDFS客户端软件实现了HDFS文件内容的校验和。当某个客户端创建一个新的HDFS文件,会计算这个文件每个block的校验和,并作为一个单独的隐藏文件保存这些校验和在同一个HDFS
namespace下。当客户端检索文件内容,它会确认从Datanode获取的数据跟相应的校验和文件中的校验和是否匹配,如果不匹配,客户端可以选择从其他Datanode获取该块的副本。

4、 元数据磁盘错误

FsImage和Editlog是HDFS的核心数据结构。这些文件如果损坏了,整个HDFS实例都将失效。因而,Namenode可以配置成支持维护多个FsImage和Editlog的拷贝。任何对FsImage或者Editlog的修改,都将同步到它们的副本上。这个同步操作可能会降低
Namenode每秒能支持处理的namespace事务。这个代价是可以接受的,因为HDFS是数据密集的,而非元数据密集。当Namenode重启的时候,它总是选取最近的一致的FsImage和Editlog使用。Namenode在HDFS是单点存在,如果Namenode所在的机器错误,手工的干预是必须的。目前,在另一台机器上重启因故障而停止服务的Namenode这个功能还没实现。

5、快照

快照支持某个时间的数据拷贝,当HDFS数据损坏的时候,可以恢复到过去一个已知正确的时间点。HDFS目前还不支持快照功能。

数据组织

数据块

兼容HDFS的应用都是处理大数据集合的。这些应用都是写数据一次,读却是一次到多次,并且读的速度要满足流式读。HDFS支持文件的write-
once-read-many语义。一个典型的block大小是64MB,因而,文件总是按照64M切分成chunk,每个chunk存储于不同的
Datanode

步骤

某个客户端创建文件的请求其实并没有立即发给Namenode,事实上,HDFS客户端会将文件数据缓存到本地的一个临时文件。应用的写被透明地重定向到这个临时文件。当这个临时文件累积的数据超过一个block的大小(默认64M),客户端才会联系Namenode。Namenode将文件名插入文件系统的层次结构中,并且分配一个数据块给它,然后返回Datanode的标识符和目标数据块给客户端。客户端将本地临时文件flush到指定的
Datanode上。当文件关闭时,在临时文件中剩余的没有flush的数据也会传输到指定的Datanode,然后客户端告诉Namenode文件已经关闭。此时Namenode才将文件创建操作提交到持久存储。如果Namenode在文件关闭前挂了,该文件将丢失。

上述方法是对通过对HDFS上运行的目标应用认真考虑的结果。如果不采用客户端缓存,由于网络速度和网络堵塞会对吞估量造成比较大的影响。

流水线复制

当某个客户端向HDFS文件写数据的时候,一开始是写入本地临时文件。假设HDFS文件的复制因子为3,当本地文件累积一块完整的用户数据,客户端就会从NameNode检索一DataNode列表。这个列表包含将会管理块的一个副本的DataNode。然后客户端开始向第一个Datanode传输数据。第一个Datanode一小部分一小部分(4kb)地接收数据,将每个部分写入本地仓库,并且同时传输该部分到第二个Datanode节点。第二个Datanode也是这样,边收边传,一小部分一小部分地收,存储在本地仓库,同时传给第三个Datanode,第三个Datanode就仅仅是接收并存储了。这就是流水线式的复制。

可访问性

HDFS给应用提供了多种访问方式。最原始的方式是通过提供应用一个java api。通过C语言封装后的这个java
API也可行。除此之外,一个HTTP浏览器同样能够用来浏览一个HDFS实体的文件。正在开发通过WebDav协议访问的方式。

FS Shell

HDFS允许以文件和目录的形式组织数据。提供了一个叫做FSshell的命令行接口来允许用户与HDFS上的数据进行交互。这个命令的语法和其他的shell(比如bash,csh)相似。这里有一些例子:

Action
Command
Create a directory named /foodir
bin/hadoop dfs -mkdir /foodir
Remove a directory named /foodir
bin/hadoop dfs -rmr /foodir
View the contents of a file named /foodir/myfile.txt
bin/hadoop dfs -cat /foodir/myfile.txt

DFSAdmin

DFSAdmin命令集用来监管HDFS集群。这些命令只有HDFS管理者才能使用。例子:

Action
Command
Put the cluster in Safemode
bin/hadoop dfsadmin -safemode enter
Generate a list of DataNodes
bin/hadoop dfsadmin -report
Recommission or decommission DataNode(s)
bin/hadoop dfsadmin -refreshNodes

浏览器接口

一个典型的HDFS安装配置了一个web服务器来通过一个可配置的TCP端口展示HDFS命名空间。这使得一个用户能够通过使用web浏览器来浏览HDFS命名空间和查看HDFS文本的内容。

空间的回收

文件的删除和恢复

用户或者应用删除某个文件,这个文件并没有立刻从HDFS中删除。相反,HDFS将这个文件重命名,并转移到/trash目录。当文件还在/trash目录时,该文件可以被迅速地恢复。文件在/trash中保存的时间是可配置的,当超过这个时间,Namenode就会将该文件从namespace中删除。文件的删除,也将释放关联该文件的数据块。注意到,在文件被用户删除和HDFS空闲空间的增加之间会有一个等待时间延迟。

当被删除的文件还保留在/trash目录中的时候,如果用户想恢复这个文件,可以检索浏览/trash目录并检索该文件。/trash目录仅仅保存被删除文件的最近一次拷贝。/trash目录与其他文件目录没有什么不同,除了一点:HDFS在该目录上应用了一个特殊的策略来自动删除文件,目前的默认策略是删除保留超过6小时的文件,这个策略以后会定义成可配置的接口。

Replication因子的减小

当某个文件的replication因子减小,Namenode会选择要删除的过剩的副本。下次心跳检测就将该信息传递给Datanode, Datanode就会移除相应的block并释放空间,同样,在调用setReplication方法和集群中的空闲空间增加之间会有一个时间延迟。

参考资料:

HDFS Java API: http://hadoop.apache.org/core/docs/current/api/

HDFS source code: http://hadoop.apache.org/core/version_control.html

原文:http://hadoop.apache.org/docs/r1.2.1/hdfs_design.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: