HDFS(Hadoop Distributed File System),作为Google File System(GFS)的实现,是Hadoop项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,可以运行于廉价的商用服务器上。它所具有的高容错、高可靠性、高可扩展性、高获得性、高吞吐率等特征为海量数据提供了不怕故障的存储,为超大数据集(Large Data Set)的应用处理带来了很多便利。
官网:https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html
适用、不适用的场景
HDFS特点:
高容错性、可构建在廉价机器上
适合批处理
适合大数据处理
流式文件访问
HDFS局限:
不支持低延迟访问
不适合小文件存储
不支持并发写入:一个文件只能有一个写,不允许多个线程同时写。
不支持修改:仅支持数据 append(追加),不支持文件的随机修改。
HDFS由四部分组成,HDFS Client、NameNode、DataNode和Secondary NameNode。
HDFS是一个主/从(Master/Slave)体系结构,HDFS集群拥有一个NameNode和一些DataNode。NameNode管理文件系统的元数据,DataNode存储实际的数据(Block默认64M)。
1、提供一些命令来管理、访问 HDFS,比如启动或者关闭HDFS。
2、与 DataNode 交互,读取或者写入数据;读取时,要与 NameNode 交互,获取文件的位置信息;写入 HDFS 的时候,Client 将文件切分成 一个一个的Block,然后进行存储。
1、管理 HDFS 的名称空间。
2、管理数据块(Block)映射信息
3、配置副本策略
4、处理客户端读写请求。
1、存储实际的数据块。
2、执行数据块的读/写操作。
1、辅助 NameNode,分担其工作量。
2、定期合并 fsimage和fsedits,并推送给NameNode。
3、在紧急情况下,可辅助恢复 NameNode。
注:并非 NameNode 的热备。当NameNode 挂掉的时候,它并不能马上替换 NameNode 并提供服务。
NameNode主要负责三个功能,分别是;(1)管理元数据 ;(2)维护目录树; (3)响应客户请求
NameNode元数据三种存储形式:
1.内存metadata(NameSystem)
2.磁盘元数据镜像文件(fsImage)
3.数据操作日志文件(edits)
注:NameSystem = fsImage + edits;当客户端对hdfs中的文件进行新增或者修改操作,操作记录首先被记入edits日志文件中,当客户端操作成功后,相应的元数据会更新到内存metadata中
namenode工作机制:
(1)第一次启动namenode格式化后,创建fsimage和edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
(2)客户端对元数据进行增删改的请求
(3)namenode记录操作日志,更新滚动日志。
(4)namenode在内存中对数据进行增删改查
注:
<1>存储文件的metadata,运行时所有数据都保存在内存中,这个的HDFS可存储的文件受限于NameNode的内存,因此,NameNode节点的内存一般都较大。
<2>NameNode失效则整个HDFS都失效了,所以要保证NameNode的可用性(SecondNameNode非NameNode的热备)。
SecondaryNameNode主要有两个作用:一是镜像备份;另一个是辅助合并NameNode的edit logs到fsimage文件中。
日志与镜像的定期合并总共分五步:
1、SecondaryNameNode通知NameNode准备提交edits文件,此时主节点产生edits.new
2、SecondaryNameNode通过http get方式获取NameNode的fsimage与edits文件(在SecondaryNameNode的current同级目录下可见到 temp.check-point或者previous-checkpoint目录,这些目录中存储着从namenode拷贝来的镜像文件)
3、SecondaryNameNode开始合并获取的上述两个文件,产生一个新的fsimage文件fsimage.ckpt
4、SecondaryNameNode用http post方式发送fsimage.ckpt至NameNode
5、NameNode将fsimage.ckpt与edits.new文件分别重命名为fsimage与edits,然后更新fstime,整个checkpoint过程到此结束。
通常情况下,SecondaryNameNode每隔一小时执行一次。 可以调整设置(hdfs-site.xml):
<property>
<name>dfs.namenode.checkpoint.txnsname>
<value>1000000value>
<description>操作动作次数description>
property>
<property>
<name>dfs.namenode.checkpoint.check.periodname>
<value>60value>
<description> 1 分钟检查一次操作次数description>
property>
DataNode就是HDFS的工作节点了,它负责存储数据,为客户端提供数据块的读写服务。在启动时会将它存储的数据块的列表发送给NameNode,根据NameNode的要求对数据块进行创建、删除和备份,还会通过心跳定期向NameNode更新存储数据块信息。
(1)一个数据块在datanode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。
(2)DataNode启动后向namenode注册,通过后,周期性(1小时)的向namenode上报所有的块信息。
(3)心跳是每3秒一次,心跳返回结果带有namenode给该datanode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个datanode的心跳,则认为该节点不可用。
(4)集群运行中可以安全加入和退出一些机器。
Hadoop2.x中HDFS的变化主要体现在增强了NameNode的水平扩展(Horizontal Scalability)及高可用性(HA)。
(1)Namespace(命名空间)的限制
由于Namenode在内存中存储所有的元数据(metadata),因此单个Namenode所能存储 的对象(文件+块)数目受到Namenode所在JVM的heap size的限制。50G的heap能够存储20亿(200 million)个对象,这20亿个对象支持4000个datanode,12PB的存储(假设文件平均大小为40MB)。
(2)性能的瓶颈
由于是单个Namenode的HDFS架构,因此整个HDFS文件系统的吞吐量受限于单个Namenode的吞吐量。
(3)隔离问题
由于HDFS仅有一个Namenode,无法隔离各个程序,因此HDFS上的一个实验程序就很有可 能影响整个HDFS上运行的程序。那么在HDFS Federation中,可以用不同的Namespace来 隔离不同的用户应用程序,使得不同Namespace Volume中的程序相互不影响。
(4)单点故障
在只有一个Namenode的HDFS中,此Namenode的宕机无疑会导致整个集群不可用。(SecondNameNode不是HA,它只是阶段性的合并 edits 和 fsimage)
单 NN 的架构使得 HDFS 在集群扩展性和性能上都有潜在的问题,当集群大到一定程度后,NN 进程使用的内存可能会达到上百 G,常用的估算公式为 1G 对应 1 百万个块,按缺省块大小计算的话,大概是 64T (这个估算比例是有比较大的富裕的,其实,即使是每个文件只有一个块,所有元数据信息也不会有 1KB/block)。同时,所有的元数据信息的读取和操作都需要与 NN 进行通信,譬如客户端的 addBlock、getBlockLocations,还有 DataNode 的 blockRecieved、sendHeartbeat、blockReport,在集群规模变大后,NN 成为了性能的瓶颈。Hadoop 2.0 里的 HDFS Federation 就是为了解决这两个问题而开发的。
官网 HDFS Federation:http://hadoop.apache.org/docs/r3.0.3/hadoop-project-dist/hadoop-hdfs/Federation.html
Federation,中文翻译为联邦,多个 NN 共用一个集群里的存储资源,每个 NN 都可以单独对外提供服务。每个 NN 都会定义一个存储池,有单独的 id,每个 DN 都为所有存储池提供存储。DN 会按照存储池 id 向其对应的 NN 汇报块信息,同时,DN 会向所有 NN 汇报本地存储可用资源情况。
几个关键概念
总结:
官网 HDFS High Availability Using the Quorum Journal Manager:http://hadoop.apache.org/docs/r3.0.3/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html
HA的大致架构,其设计上的考虑包括:
我们不能在NN进程内进行心跳等信息同步,最简单的原因,一次FullGC就可以让NN挂起十几分钟,所以,必须要有一个独立的短小精悍的watchdog来专门负责监控。这也是一个松耦合的设计,便于扩展或更改,目前版本里是用ZooKeeper(以下简称ZK)来做同步锁,但用户可以方便的把这个ZooKeeper FailoverController(以下简称ZKFC)替换为其他的HA方案或leader选举方案。
1.共享存储fencing,确保只有一个NN可以写入edits。
2.客户端fencing,确保只有一个NN可以响应客户端的请求。
3.DataNode fencing,确保只有一个NN可以向DN下发命令,譬如删除块,复制块,等等。
从图中可以看出,整个切换过程是由ZKFC来控制的,具体又可分为HealthMonitor、ZKFailoverController和ActiveStandbyElector三个组件。
在故障切换期间,ZooKeeper主要是发挥什么作用呢,有以下几点:
那在哪些场景会触发自动切换呢,从HDFS-2185中归纳了以下几个场景:
就是 NameService。Hadoop 2.0 里对 NN 进行了一层抽象,提供服务的不再是 NN 本身,而是 NameService(以下简称 NS)。Federation 是由多个 NS 组成的,每个 NS 又是由一个或两个 (HA)NN 组成的。
图中 DN-1 到 DN-6 是六个 DataNode,NN-1 到 NN-4 是四个 NameNode,分别组成两个 HA 的 NS,再通过 Federation 组合对外提供服务。Storage Pool 1 和 Storage Pool 2 分别对应这两个 NS。我们在客户端进行了挂载表的映射,把 /share 映射到 NS1,把 /user 映射到 NS2,这个映射其实不光是要指定 NS,还需要指定到其上的某个目录。
配置见:hadoop2.0 federation与HA的配置
1、共享存储的fencing,确保只有一个NN能写成功。使用QJM实现fencing。
2、datanode的fencing。确保只有一个NN能命令DN。
(a) 每个NN改变状态的时候,向DN发送自己的状态和一个序列号。
(b) DN在运行过程中维护此序列号,当failover时,新的NN在返回DN心跳时会返回自己的active状态和一个更大的序列号。DN接收到这个返回是认为该NN为新的active。
© 如果这时原来的active(比如GC)恢复,返回给DN的心跳信息包含active状态和原来的序列号,这时DN就会拒绝这个NN的命令。
(d) 特别需要注意的一点是,上述实现还不够完善,HDFS-1972中还解决了一些有可能导致误删除block的隐患,在failover后,active在DN汇报所有删除报告前不应该删除任何block。
3、客户端fencing,确保只有一个NN能响应客户端请求。
hadoop2.0的HA 机制有两个namenode,一个是active namenode,状态是active;另外一个是standby namenode,状态是standby。两者的状态是可以切换的,但不能同时两个都是active状态,最多只有1个是active状态。只有active namenode提供对外的服务,standby namenode是不对外服务的。active namenode和standby namenode之间通过NFS或者JN(journalnode,QJM方式)来同步数据。
active namenode会把最近的操作记录写到本地的一个edits文件中(edits file),并传输到NFS或者JN中。standby namenode定期的检查,从NFS或者JN把最近的edit文件读过来,然后把edits文件和fsimage文件合并成一个新的fsimage,合并完成之后会通知active namenode获取这个新fsimage。active namenode获得这个新的fsimage文件之后,替换原来旧的fsimage文件。
这样,保持了active namenode和standby namenode的数据的实时同步,standby namenode可以随时切换成active namenode(譬如active namenode挂了)。而且还有一个原来hadoop1.0的secondarynamenode,checkpointnode,buckcupnode的功能:合并edits文件和fsimage文件,使fsimage文件一直保持更新。所以启动了hadoop2.0的HA机制之后,secondarynamenode,checkpointnode,buckcupnode这些都不需要了。
Hadoop1.x都是64M,hadoop2.x开始都是128M。
HDFS核心技术详解:https://blog.csdn.net/wypersist/article/details/79757242
HDFS文件系统:https://blog.csdn.net/c391183914/article/details/78658486
HDFS的NameNode工作机制:https://www.cnblogs.com/yaboya/p/9193508.html
HDFS-DataNode工作机制:https://my.oschina.net/u/3091870/blog/3000611
High
Availability
for
the
HDFS
Namenode:https://issues.apache.org/jira/browse/HDFS-1623
Hadoop 2.0 NameNode HA 和 Federation 实践:https://www.infoq.cn/article/hadoop-2-0-namenode-ha-federation-practice-zh
hadoop2—namenode—HA原理详解:https://www.cnblogs.com/sy270321/p/4398815.html
HDFS Federation HA 混合环境介绍:https://www.jianshu.com/p/80582687851f
hadoop2.0 federation与HA的配置:https://blog.51cto.com/sstudent/1392447
HDFS HA和Federation安装部署方法:http://dongxicheng.org/hadoop-hdfs/hdfs-ha-federation-deploy/