原文地址:pengtuo.tech/2018/09/10/…html
Hadoop
生态是一个庞大的、功能齐全的生态,可是围绕的仍是名为 Hadoop
的分布式系统基础架构,其核心组件由四个部分组成,分别是:Common
、HDFS
、MapReduce
以及 YARN
。node
Common
是 Hadoop
架构的通用组件;HDFS
是 Hadoop
的分布式文件存储系统;MapReduce
是Hadoop
提供的一种编程模型,可用于大规模数据集的并行运算;YARN
是 Hadoop
架构升级后,目前普遍使用的资源管理器。小目标是为每个核心组件写一篇全解的博文,本篇先来好好了解下 HDFS
。apache
HDFS(The Hadoop Distributed File System),是被设计成适合运行在通用硬件(commodity hardware
)上的 Hadoop
的分布式文件系统。它与其余的分布式系统有很是显著的不一样,首先 HDFS
具备高容错性,而且它能够被部署到廉价的硬件上。此外,HDFS
提供对应用程序数据的高吞吐量访问,适用于具备大型数据集的应用程序。编程
目前,HDFS
做为 Apache Hadoop
的核心项目,URL为:hadoop.apache.org/api
一个 HDFS
实例有可能包含数百台或数千台服务器,每个台机器都存储文件系统数据的一部分,这种状况下硬件故障是常态。而 HDFS
可检测故障并从中快速自动恢复。服务器
HDFS
设计用于批处理而不是用户的交互式使用,其重点是数据访问的高吞吐量而并不追求数据访问的低延迟。网络
HDFS
的核心目标就是为处理具备大数据量的应用,在其上运行的应用的文件大小通常都为 TB
级别。HDFS
可提供高聚合数据带宽而且要扩展到集群中的数百个节点上,并对于单个应用可支持上千万个文件。架构
HDFS
应用程序是一个"一次写入屡次读取"的文件访问模型。这种模型能够简化数据的一致性问题而且可以实现高吞吐数据访问。官方文档表示有计划支持追加写入文件的功能。分布式
“Moving Computation is Cheaper than Moving Data”,当一个计算程序与数据同在一个物理节点上时,运算最高效,特别是当数据量特别大时,移动计算远优于移动数据集。移动计算能够最大限度地减小网络拥塞并提升系统的总体吞吐量。HDFS
设计的是将计算迁移到更靠近数据所在的位置,而不是将数据移动到运行应用程序的位置。HDFS
为应用程序提供了接口,使其自身更靠近数据。oop
HDFS
的设计便于从一个平台移植到另外一个平台。 这有助于普遍采用 HDFS
做为大量应用程序的首选大数据处理平台。
NameNode
与 DataNode
是 HDFS
系统的重要知识点。HDFS
是 master/slave
体系结构。一个 HDFS
集群是由单个 NameNode
和众多 DataNode
组成,文件会被分红一个或多个块,这些块存储在一组 DataNode
中。
由于 HDFS
是用 Java 语言搭建的,因此只要是支持 Java 语言的机器均可以运行 NameNode
和 DataNode
。而且由于 Java 的高可移植性,HDFS
也具备很是普遍的应用范围。一种典型的 HDFS
部署模式是指定一个物理主机运行 NameNode
,而后其他的机器运行 DataNode
,在实际部署状况中,通常都是一台主机部署一个 DataNode
。
群集中存在单个 NameNode
极大地简化了系统的体系结构。 NameNode
是全部 HDFS
元数据的决定者和存储库。系统的这种设计使用户数据永远不会流经 NameNode
,可理解 NameNode
为整个系统的中枢。
架构以下图:
首先图中的 rack
翻译为“机架”,能够理解为两个处于不一样地方的机群,每一个机群内部有本身的链接方式。其次在 DataNode
中存储的不是当个文件,而是文件块(Block),在 HDFS
中,每一个大文件会拆分红多个 Block
,而后将这些 Block
散布存储在不一样的 DataNode
中,而且每一个 Block
会有多个复制,也会存储到其余的 DataNode
中。
能够看出上图分别解释了“读”和“写”两种操做:
HDFS
写入文件时,图中将文件拆分的 Block
写入到了两个机架的 DataNode
中,通常状况下就是两个机架的两个物理主机中,能够看出文件数据没有通过 NameNode
。数据写入的过程见(“7、数据复制流水线”)HDFS
读取文件时,会将操做命令传向 NameNode
,而后 NameNode
转为对应的数据块的操做,指挥相应的 DataNode
将所需数据返回给客户端。还有一个节点图中没有显示,叫做
Secondary Namenode
,是辅助后台程序,主要负责与NameNode
进行通讯,按期保存HDFS
元数据的快照及备份其余NameNode
中的内容,平常Standby
,当NameNode
故障时顶替NameNode
使用。
NameNode
是管理文件系统命名空间的主服务器,用于管理客户端对文件的访问,执行文件系统命名空间操做,如打开,关闭和重命名文件和目录。它还肯定了Block
到 DataNode
的映射。
NameNode
作着有关块复制的全部决定,它按期从群集中的每一个 DataNode
接收 Heartbeat
和 Blockreport
。收到 Heartbeat
意味着 DataNode
正常运行,Blockreport
包含 DataNode
上全部块的列表。
DataNode
一般是群集中每一个节点一个,用于存储数据,负责提供来自文件系统客户端的读写请求。而且还会根据 NameNode
的指令执行块建立,删除和复制。
HDFS
支持传统的分层文件组织,文件系统命名空间层次结构与大多数其余现有文件系统相似,一个用户或者应用能够建立文件夹而且在这个文件夹里存储文件。可是 HDFS
不支持 Linux 里的硬连接和软链接。NameNode
维护着文件系统的命名空间,其记录对文件系统命名空间或其属性的任何更改,NameNode
还会存储复制因子。
数据块的副本数称为该数据块的复制因子
文件系统的元数据(MetaData
)也存储在 NameNode
中,NameNode
使用名为 EditLog
的事务日志来持久记录文件系统元数据发生的每一个更改。例如,在 HDFS
中建立新文件会致使 NameNode
将记录插入 EditLog
,以指示此状况。NameNode
使用其本地主机OS文件系统中的文件来存储 EditLog
。
而整个文件系统命名空间(包括块到文件和文件系统属性的映射)存储在名为 FsImage
的文件中。 FsImage
也做为文件存储在 NameNode
的本地文件系统中。
NameNode
在整个内存中保存整个文件系统命名空间和文件的数据块映射。当 NameNode
启动,或者检查点由可配置的阈值触发时,它从磁盘读取 FsImage
和 EditLog
,并先将 FsImage
中的文件系统元数据信息加载到内存,而后把 EditLog
中的全部事务应用到内存中的 FsImage
,最后将此新版本同步到磁盘上的 FsImage
。而后它能够截断旧的 EditLog
,由于它的事务已应用于持久性 FsImage
。此过程称为检查点。
检查点的目的是经过获取文件系统元数据的快照并将其保存到 FsImage
来确保 HDFS
具备文件系统元数据的一致视图。尽管直接从内存中读取 FsImage
很高效,但直接对 FsImage
进行增量编辑效率不高。咱们不会修改每一个编辑的 FsImage
,而是在 Editlog
中保留编辑内容。
在检查点期间,Editlog
的更改将应用于 FsImage
。能够以秒为单位的给定时间间隔(dfs.namenode.checkpoint.period)触发检查点,或者在累积给定数量的文件系统事务(dfs.namenode.checkpoint.txns)以后触发检查点。若是同时设置了这两个属性,则一旦知足其中一个阈值就可触发检查点。
HDFS
旨在跨大型集群中的计算机可靠地存储很是大的文件。它将每一个文件存储为一系列块,除最后一个块以外的文件中的全部块都具备相同的大小,HDFS
使用的默认块大小为 128MB。复制文件的块以实现容错,且通常复制出的文件块会存储到不一样的 DataNode
中。数据块的大小以及复制因子都是能够由用户设置。
HDFS中的文件是一次写入的,而且在任什么时候候都只能有一个写入器。
解释:如图所示,part-0
文件复制因子为r:2
,其拆分的数据块号有{1,3}
,因此 1 号数据块在第1,第3个 DataNode
上,3 号数据块在第5,第6个DataNode
上;part-1
文件解释同理。而这些信息都存储在 NameNode
中。
刚刚只是简单的介绍了图里的信息,实际 HDFS
副本放置策略是一个值得研究的课题,由于这切实关系到 HDFS
的可依赖性与表现,而且通过优化的副本放置策略也使得 HDFS
相比其余分布式文件系统具备优点。
在大部分的实际案例中,当复制因子是 r = 3
时,HDFS
的放置策略是将一个复制品放置到写入器操做的 DataNode
中,第二个复制品放置到另外一个远程机架上的一个节点中,而后最后一个复制品则放置同一个远程机架的不一样物理节点中。
这种放置策略能够有效的减小机架之中的通讯以提升系统的表现。由于不一样机架的物理节点的通讯须要经过交换机,而在大多数状况下,同一机架中的计算机之间的网络带宽大于不一样机架中的计算机之间的网络带宽。
若是复制因子大于3,则随机肯定第4个及之后副本的放置,同时保持每一个机架的副本数量低于上限。
上限数通常为(副本数-1)/ 机架 + 2
因为 NameNode
不容许 DataNode
具备同一块的多个副本,所以,能建立的最大副本数是此时 DataNode
的总数。
当有客户端请求读取时,HDFS
为了最小化全局带宽消耗与读取延迟,会优先选择离读取客户端最近的数据副本。
全部 HDFS
通讯协议都分层在 TCP/IP
协议之上。
当客户端将数据写入复制因子为 r = 3
的 HDFS
文件时,NameNode
使用 replication target choosing algorithm
检索 DataNode
列表。此列表包含将承载该块副本的 DataNode
。
而后客户端向第一个 DataNode
写入,第一个 DataNode
开始分批接收数据,将每一个部分写入其本地存储,并将该部分传输到列表中的第二个 DataNode
。第二个 DataNode
又开始接收数据块的每一个部分,将该部分写入其存储,而后将该部分刷新到第三个 DataNode
。最后,第三个 DataNode
将数据写入其本地存储。
可见,DataNode
是从流水线中的前一个接收数据,同时将数据转发到流水线中的下一个,数据是从一个 DataNode
流水线到下一个 DataNode
。
应用能够以多种方式操控 HDFS
上的文件,其中经过 FS Shell
能够像操控 Linux
文件系统通常,经常使用命令有:
Action | Command |
---|---|
建立 foodir 文件夹 | bin/hadoop fs -mkdir /foodir |
删除文件夹 | bin/hadoop fs -rm -R /foodir |
查看文件内容 | bin/hdfs dfs -cat /foodir/myfile.txt |
上传文件 | bin/hdfs dfs -copyFromLocal ~/a.txt /foodir/ |
…… | …… |
会发现这里有两种命令前缀,一个是
hadoop fs
,一个是hdfs dfs
区别是:
hadoop fs
能够用于其余文件系统,不止是hdfs文件系统内,也就是说该命令的使用范围更广;而hdfs dfs
专门针对hdfs分布式文件系统。还有一个前缀为
hadoop dfs
,这个已通过时,建议不要使用🙅。
若是启用了垃圾箱配置,则 FS Shell
删除的文件不会当即从 HDFS
中删除,而是 HDFS
将其移动到垃圾目录(/user/username/.Trash)。
在垃圾箱中,被删除文件的生命周期到期后,NameNode
将从 HDFS
命名空间中删除该文件。删除文件会致使释放与文件关联的块。
注意:在用户删除文件的时间与
HDFS
中相应增长的可用空间之间可能存在明显的时间延迟。
若是启用了垃圾箱配置,想直接完全删除,命令为:hadoop fs -rm -r -skipTrash a.txt
当文件的复制因子减小时,NameNode
选择能够删除的多余副本。下一个 Heartbeat
将此信息传输到 DataNode
。而后,DataNode
删除相应的块,并在群集中显示相应的可用空间。
[1] Hadoop JavaDoc API
[2] HDFS 源码: hadoop.apache.org/version_con…
[3] HDFS 文档: hadoop.apache.org/docs/stable…