Apache Hadoop文档翻译之一(HDFS架构)

Apache Hadoop项目为高可用、可扩展、分布式计算开发开源软件。Apache Hadoop软件库是一个平台,它使用简单的编程模型让跨机器上大数据量的分布式计算变得简单。 它旨在从单个服务器扩展到数千台计算机,每台计算机都提供本地计算和存储。库自己被设计用来在软件层面检测和处理故障,而不是依赖硬件来提供高可用性,所以,在计算机集群之上提供高可用性服务,每一个计算机均可能容易出现故障。html

介绍

HDFS是一个被设计用来运行在商用机器上的分布式文件系统。它跟现有的分布式文件系统有不少类似之处,可是,区别也很大。HDFS容错率高,而且被设计为部署在廉价机器上。HDFS提供对应用程序数据的高吞吐量访问,适用于具备大型数据集的应用程序。HDFS放宽了一些POSIX要求,以实现对文件系统数据的流式访问。HDFS最开始被构建是用来做为Nutch搜索引擎项目的基础设施。HDFS是Apache hadoop核心项目的一部分。项目地址:hadoop.apache.org/node

假设和目标

硬件故障

硬件故障很常见。一个HDFS示例应该是包含成百上千台服务器,每台服务器保存文件系统的部分数据。事实上,存在大量组件而且每一个组件都有可能出现故障,这意外着有些组件可能一直没法正常工做。所以,检测故障而且自动从故障中快速恢复是HDFS架构的核心目标。linux

流数据访问

在HDFS上运行的程序须要对其数据集进行流式访问。它们不是运行在普通文件系统上的普通应用程序。HDFS被设计更可能是做为批处理来使用,而不是用户的交互式使用。重点是数据访问的高吞吐量而不是数据访问的低延迟。POSIX强加了许多针对HDFS的应用程序不须要的硬性要求。web

大数据集

运行在HDFS上的程序用户大量的数据集。HDFS中,一个普通文件能够达到千兆到太字节。所以,HDFS调整为支持大文件。它应该提供高聚合数据带宽并扩展到单个集群中的数百个节点。 它应该在单个实例中支持数千万个文件。算法

简单的一致性模型

HDFS程序须要一个一次写入屡次读取的文件访问模型。一次建立、写入和关闭的文件,除了追加和截断以外,不须要更改。能够在文件尾部追加内容,可是不能在任意位置进行修改。这种假设简化了一致性问题,而且提升了数据访问的吞吐量。这种模型很是适合Mapreduce程序以及网络爬虫。shell

移动计算比移动数据代价更小

当计算所须要的数据距离计算越近时,计算的效率越高,当数据量越大时,这个效率提高更明显。越少的网络阻塞越能提升系统总体的吞吐量。这样,咱们能够认为,将计算迁移到数据附近比将数据迁移到计算附近更高效。HHDFS为应用程序提供了接口,使其自身更靠近数据所在的位置。apache

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

HDFS被设计成易于从一个平台移植到另外一个平台。这有助于HDFS的普及。编程

Namenode和DataNodes

HDFS有一个主从架构。一个HDFS集群包含一个Namenode,Namenode管理文件系统的命名空间以及调整客户端对文件的访问。此外,还有必定数量的Datanode,集群中一般一个节点一个Datanode,用来管理其运行节点上的存储。HDFS公开文件系统命名空间,并容许用户数据存储在文件中。集群内部,一个文件被分红一个或多个blocks而且这些blocks存储在一些Datanode上。Namenode执行文件系统命名空间操做,例如打开、关闭、重命名文件和文件夹。Namenode还决定blocks到Datanode的映射。Datanode负责服务于系统客户端的读和写。DataNode还根据NameNode的指令执行块建立,删除和复制。 api

Namenode和Datanode时设计用于运行在商用机器上的软件。这些机器一般运行linux操做系统。HDFS是JAVA语言编写的,因此任何支持JAVA的机器都能运行Namenode和Datanode软件。使用高度可移植的Java语言意味着HDFS能够部署在各类各样的机器上。广泛的部署方式是在一台专用机器上单独运行Namenode软件。集群中其余机器运行Datanode软件。架构支持在一台机器上运行多个Datanode,可是实际部署不多这样作。 一个集群中只存在一个Namenode极大简化了系统的架构。Namenode管理整个HDFS的元数据。系统被设计为任何用户数据都不流经Namenode。浏览器

文件系统命名空间

HDFS支持传统的文件分层组织。用户或程序能够建立目录以及保存文件到目录中。HDFS文件系统命名空间层次结构跟其余现有文件系统相似:好比建立文件和删除文件,将文件从一个目录移到另外一个目录,或者重命名文件。HDFS支持用户配额访问权限。HDFS不支持硬链接或软链接,可是不排除在将来的版本中实现。 Namenode维护文件系统的命名空间。文件系统命名空间或其属性的更改都由Namenode来记录。应用程序能够指定文件的副本数量,该文本由HDFS来维护。文件的副本数称为该文件的复制因子,该信息由NameNode存储。

数据复制

HDFS被设计用来可靠地在集群中大量机器上存储大文件。它以一系列块的形式保存每个文件。文件块被复制多份以提升容错性。每一个文件的块大小和复制因子是可配置的。 一个文件除了最后一个块之外,其余块都是相同大小。当设置块长度可变时,用户能够开启一个新的块而不须要在最后的块上进行追加以达到配置的固定大小。 应用程序能够指定文件的副本数量。复制因子在文件建立时指定并能在随后进行修改。HDFS中文件是一次性写入(除非追加和截断)而且任什么时候候只有一个写入者。 有关块的复制,NameNode全权负责。Namenode按期接收集群中Datanode的心跳和块信息报告。接收到心跳代表Datanode正常工做。块信息报告(Blockreport)包含DataNode上全部块的列表。

副本选址

副本的选址对HDFS的可靠性和性能起到相当重要的做用。优化副本的选址使HDFS区别于其余分布式文件系统。这是一个须要大量调试和经验的特性。机架感知式的选址策略的目标是为了提供数据可靠性、可用性以及带宽利用率。目前的副本选址策略的实现是在这个方向上的第一次努力。实现这个策略的短时间目标是在生产系统中进行验证,掌握更多行为并创建一个基础来测试和研究更加复杂的策略。

HDFS运行在一系列的集群主机上,这些主机一般分布在各个机架上。跨机架上的两个不一样主机间信息交换须要通过交换机。在大多数状况下,同一机架中的计算机之间的网络带宽大于不一样机架中的计算机之间的网络带宽。

Namenode经过Hadoop Rack Awareness 过程来决定每一个Datanode隶属于哪一个机架id。一个简单可是非最佳的策略是将副本放在不一样机架上。这样,当一整个机架出现故障时可以防止数据丢失,而且读取数据能使用到不一样机架上的带宽。可是,这种策略增长了写操做代价,由于须要传输块到不一样机架上。

当副本数为3时,HDFS放置策略一般是将一个副本放在本机架的一个节点上,将另外一个副本放在本机架的另外一个节点,最后一个副本放在不一样机架的不一样节点上。该策略能够减小机架之间写入流量,从而提升写入性能。机架出现故障的几率要比机器出现故障的几率低,这个策略不会影响数据可靠性和可用性的保证。但这种策略会下降数据读取时的网络带宽,由于数据只放置在两个机架上而不是三个。这种策略下,文件的副本不是均匀的分布在各个机架上。三分一个的副本放置在一个节点上,三分之二的副本放置在一个机架上,而另外三分之一均匀分布在剩余的机架上。这个策略提升了写性能而不影响数据可靠性和读性能。

当前,这里介绍的默认副本放置策略是一项正在进行的工做。

副本选择

为了下降带宽消耗以及读取延时,HDFS尝试让须要读取的副本跟读取者更近。若是存在一个副本在客户端节点所在的同个机架上,那么这个副本是知足读取需求的首选。若是HDFS集群横跨多个数据中心,那么在本地数据中心的副本将是优先于其余远程副本。

安全模式

Namenode刚启动时会进入一个特殊阶段,咱们称这个阶段为安全模式。当Namenode处于安全模式时,不会发生数据块的复制。Namenode接收来自Datanode的心跳以及块报告信息。块报告包含Datanode持有的一些列数据块。每一个块都指定最小副本数。当一个数据块被NameNode检查确保它知足最小副本时数,它被认为是安全的。数据被Namenode检入,当检入达到一个百分比(该百分比可配置)时,Namenode退出安全模式。而后Namenode会确认那些副本数小于指定数量的数据块列表,而且复制这些块到其余Datanode上。

文件系统元数据的持久性

HDFS命名空间保存在Namenode上。NmaeNode使用一个称之为EditLog的事务日志持续地记录发生在文件系统元数据的每个改变。例如,在HDFS中建立一个文件,Namenode将插入一条记录到EditLog中。一样,修改文件的复制因子也会致使一条新的记录插入EditLog中。Namenode使用本地操做系统文件来保存EditLog。整个文件系统命名空间(包括块到文件的映射以及文件系统属性)存储在一个称为FsImage的文件中。FsImage一样存储在Namenode的本地文件系统中。

Namenode将整个文件系统的命名空间以及块映射信息保存在内存中。当Namenode启动时,或者可配置阈值的检查点被触发时,Namenode便从磁盘中读取FsImage和EditLog,将EditLog中的事务应用到表示FsImage的内存中,而后将最新的FsImage内存刷新到磁盘上。而后能够截断旧的EditLog,由于新版的EditLog已经持久化到FsImage中。以上整个过程称为检查点(checkpoint)。检查点的目的是经过获取文件系统元数据的快照并将其保存到FsImage来确保HDFS具备文件系统元数据的一致视图。即便读取FsImage很高效,直接向FsImage增长编辑并不高效。所以针对每次编辑,咱们会放在EditLog中而不是直接修改FsImage。检查点期间,EditLog的变动信息会应用到FsImage上。能够以秒为单位的给定时间间隔(dfs.namenode.checkpoint.period)触发检查点,或者在累积给定数量的文件系统事务(dfs.namenode.checkpoint.txns)以后触发检查点。当二者均被设置,则哪一个先生效就直接触发检查点。

Datanode将HDFS数据保存在本地文件系统的文件中。Datanode对HDFS文件没有意识,它只是保存HDFS数据的每一个块,并保存在本地文件系统中的各个文件中。Datanode不会在相同目录下建立全部文件,而是每一个目录中有一个最佳文件数,并适当建立子目录。将全部文件放在同一个目录下不太明智,由于本地文件系统或许不能有效支持在一个目录下面存放海量文件。当一个Datanode启动时,它将扫描本地文件系统,生成全部HDFS数据块的列表(这些数据块对应每个本地文件),并发送报告给Namenode。这个报告咱们称之为块报告。

通信协议

全部HDFS协议均位于TCP/IP之上。一个客户端创建一个链接到Namenode机器上的TCP端口(端口可配置)上。它使用客户端协议与NameNode通信。Datanode使用Datanode协议与Namenode进行通信。一个远程过程调用(RPC)封装了客户端协议以及Datanode协议。按照设计,NameNode永远不会启动任何RPC。 相反,它只响应DataNodes或客户端发出的RPC请求。

鲁棒性

HDFS的主要目标是即便在出现故障时也能可靠地存储数据。三种常见的故障有:Namanode故障、Datanode故障以及网络分裂?

数据磁盘故障,心跳以及从新复制

每一个Datanode会按期地发送心跳信息给你Namenode。网络分裂会致使部分Datanode失去与Namenode的联系。Namenode经过收不到Datanode的心跳信息来收集这个失联信息。Namenode标记近期没有心跳信息的Datanode,并终止对这些Datanode的IO请求。在已经死亡的DataNode注册的任何数据在HDFS将不能再有效。Datanode故障会致使一些块的复制因子低于它们的指定值。NameNode时常地跟踪数据块是否须要被复制并在必要的时候启动复制。多个缘由会致使从新复制的操做,例如:Datanode不可用,副本损坏,Datanode磁盘损坏,或者文件的复制因子增大。

将DatNode标记为死亡的超时时间适当地加长(默认超过10分钟)是为了不DataNode状态改变引发的复制风暴。针对性能敏感的状况,用户能够经过配置来设置更短的时间间隔来标记DataNode为失效,尽可能避免失效的节点还继续参与读写操做。

集群从新平衡

HDFS架构兼容数据再平衡方案。当一个Datanode上的剩余空间降到必定阈值时,方案应该自动将该Datanode上的数据迁移到其余Datanode上。对于一些特定文件的突发需求,方案应动态地建立额外的副本并从新平衡集群中的其余数据。这种方案暂时还未实现。

数据完整性

从DataNode获取的数据块可能已损坏。发生损坏的缘由多是存储设备的故障、网络故障或者缺陷软件。HDFS客户端软件对HDFS文件的内容进行校验和检查。当客户端建立一个HDFS文件,它会计算文件的每个数据块的校验和,并将这些校验和储存在HDFS命名空间中一个单独的隐藏的文件当中。当客户端从DataNode得到数据时会对对其进行校验和,而且将之与储存在相关校验和文件中的校验和进行匹配。若是没有,客户端会选择从另外一个拥有该数据块副本的DataNode上恢复数据。

元数据磁盘故障

FsImage和EditLog是HDFS的核心数据架构。这些文件的故障会致使HDFS实例没法工做。由于这个缘由,HDFS能够被配置成支持多份FsImage和EditLog备份。任何对FsImage和EditLog的更新,都会致使其余全部FsImage和EditLog的同步更新。同步更新多份FsImge和EditLog下降NameNode能支持的每秒更新命名空间事务的频率。然而,频率的下降是能够被接受,尽管HDFS应用本质上是对数据敏感,但不是对元数据敏感。当一个NameNode从新启动,他会选择最新的FsImage和EditLog来使用。另外一个增长容错性已达到高可用性的选项是使用多个Namenodes,这个选项的具体实现能够为:文件系统的共享存储分布式的编辑日志(称为Journal)。后面会介绍使用方法。

快照

快照支持在特定的时间(瞬间)保存数据的副本。咱们使用的快照特征多是将损坏的HDFS实例回退到先前一个正常版本。

Data Organization

数据块

HDFS被设计成支持很是大的文件。与HDFS兼容的应用程序是处理大型数据集的应用程序。这些程序一次写入数据屡次读取,而且这些读操做知足流式的速度。HDFS支持一次写入屡次读取的文件语义。HDFS中,一个典型的块大小是128兆。所以,一个HDFS文件会被切割成128M大小的块,若是能够的话,每个大块都会分属于一个不一样的DatNode。

复制流水线

当客户端按照3个副本数来写数据到HDFS文件中,Namenode使用副本目标选择算法来获取Datanode列表。这个列表包含块副本将落地的Datanode。而后客户端将数据写入第一个Datanode。第一个Datanode开始分部分接收数据,将每一个部分写入其本地存储,并将该部分传输到列表中的第二个Datanode。第二个Datanode开始接收数据块的每一个部分并写入本地存储而后传输到第三个Datanode。最后,第三个Datanode将数据写入本地存储。所以,一个Dataode可以从上一个节点接收数据据并在同一时间将数据转发给下一个节点。所以,数据在管道中从一个DataNode传输到下一个(复制流水线)。

可访问性

应用程序能够经过多种方式来访问HDFS。HDFS自己提供FileSystem Java API让应用程序来访问,这个Java Api的C语言封装版本以及REST API一样能够供用户使用。另外,一个HTTP浏览器也能够访问HDFS实例中的文件。使用MFS gateway,HDFS能被安装做为本地文件系统的一部分。

FS Shell

HDFS提供一个称为FS Shell的命令行接口,方便用户与HDFS中的数据进行交互。这写命令集合的语法跟其余咱们熟悉的命令十分类似(例如bash,csh)。下面是一些动做/命令对的示例:

动做 命令
建立目录 bin/hadoop dfs -mkdir /foodir
删除目录 bin/hadoop fs -rm -R /foodir
查看文件内容 bin/hadoop dfs -cat /foodir/myfile.txt

DFSAdmin

DFSAdmin命令集是用来管理HDFS集群。只有HDFS管理者才能使用这些命令。下面是一些动做/命令对的示例:

动做 命令
Put the cluster in Safemode bin/hdfs dfsadmin -safemode enter
Generate a list of DataNodes bin/hdfs dfsadmin -report
Recommission or decommission DataNode(s) bin/hdfs dfsadmin -refreshNode

浏览器界面

A typical HDFS install configures a web server to expose the HDFS namespace through a configurable TCP port. This allows a user to navigate the HDFS namespace and view the contents of its files using a web browser.

一般安装HDFS时会配置一个web服务,经过一个配置好的TCP端口来暴露HDFS命名空间。它容许用户看到HDFS命名空间,并能使用web浏览器来查看文件内容。

空间回收

文件的删除和恢复

若是垃圾配置可用,使用HDFS SHELL删除的文件不会马上从HDFS删除,而是被移动到垃圾目录(每一个用户都有本身的垃圾目录:/user//.Trash),文件只要在垃圾目录中,能够随时进行恢复。

大部分刚删除的文件都被移动到垃圾目录中(/user//.Trash/Current),而且在一个可配置的间隔时间内,HDFS为当前垃圾目录中的文件建立检查点(under /user//.Trash/),同时删除那些过时的检查点。垃圾检查点信息请点击expunge command of FS shell

当回收站中的文件过时后,Namenode会从HDFS命名空间中删除该文件。文件的删除会致使跟该文件相关联的块被释放。须要说明的是文件被用户删除的时间和对应的释放空间的时间之间有一个明显的时间延迟。

下面的例子将展现如何经过FS SHELL将文件从HDFS中删除。咱们在要删除的目录中建立test1和test2两个文件

$ hadoop fs -mkdir -p delete/test1
$ hadoop fs -mkdir -p delete/test2
$ hadoop fs -ls delete/
Found 2 items
drwxr-xr-x   - hadoop hadoop          0 2015-05-08 12:39 delete/test1
drwxr-xr-x   - hadoop hadoop          0 2015-05-08 12:40 delete/test2
复制代码

咱们将删除test1文件,下面的日志显示文件被移动到垃圾目录中

$ hadoop fs -rm -r delete/test1
Moved: hdfs://localhost:8020/user/hadoop/delete/test1 to trash at: hdfs://localhost:8020/user/hadoop/.Trash/Current
复制代码

如今我来执行将文件删除跳过垃圾目录选项(skipTrash),文件则不会转移到垃圾目录。文件将彻底从HDFS中移除。

$ hadoop fs -rm -r -skipTrash delete/test2
Deleted delete/test2
复制代码

如今在垃圾目录中,咱们只能看到test1文件

$ hadoop fs -ls .Trash/Current/user/hadoop/delete/
Found 1 items\
drwxr-xr-x   - hadoop hadoop          0 2015-05-08 12:39 .Trash/Current/user/hadoop/delete/test1
复制代码

也就是test1进入垃圾目录,而test2被永久删除。

复制因子减小

当文件的复制因子减少时,NameNode将在能够删除的副本中选中多余的副本。在下一个心跳通信中将该信息传输给DataNode。而后DataNode移除对应的数据块而且释放对应的空间。再重申一遍,在完成复制因子的设置和集群中出现新的空间之间有个时间延迟。

参考

Hadoop Java API HDFS源码: hadoop.apache.org/version_con…

相关文章
相关标签/搜索