通过之前(上一篇HDFS的博客)的学习我们已经了解到了hdfs的一些大致基本情况,这篇博客主要补充一下针对HDFS1.0的不足,HDFS2.0的HA机制和Federation机制。
先对之前的学习做个小概括:
hadoop的特点有:
HDFS作为hadoop的分布式存储系统,具有:能处理超大文件,运行于廉价机器集群和流式访问数据。
同样的这些优点的背后就有它的局限:它不适合处理低延迟数据的访问,无法高效存储大量小文件,不支持多用户写入及任意修改文件。HDFS的设计建立在”一次写入,多次读写“任务的基础上,每个文件只有一个写入者,而且写操作只能在文件末尾完成,即只能执行追加操作。
在前面的博客中有提到HDFS的冗余存储机制,这里仔细记录一下,数据副本的存放策略。HDFS将每个文件进行分块存储,同时一个数据块又有多个副本,这些副本如何分布在不同机器上呢?
放在同一台机器肯定是不行的,这样冗余存储就没什么意义了,一种简单但没有优化的方法是放在不同的机架上,这样可以有效防止一台机架出了问题后数据的丢失,并且允许读数据时候 充分利用多个机架之间的带宽,通过将副本均匀分布在集群中,有利于组件失效情况下的负载均衡。
但是这种策略,一个写操作就需要将数据传输到各个机架,因而增大了写操作的代价。HDFS的默认副本数目是3,目前的操作是:
1、第一块,在本机器的HDFS目录下存储一个block
2、第二块,另寻一个机架的某个DataNode上存放
3、第三块,在该机架的同一个机架上找某一台机器存放最后一块。
这样,就减少了机架间的数据传输,提高了写操作的效率,而且能保证对这个块的访问能优先在本机架上找到,如果这一整个机架出现了问题,也可以在另外的机架(Rack)上找到。
Hadoop2.0之前,NameNode是单个集群的故障点,NameNode作为集群首脑,存放着集群中所有的元数据,一旦节点出错,将导致整个集群不可用,为了解决这个问题,HA(高可靠性)就被引入了。在这一实现中,配置了一对活动(active)-备用(standby)名称节点(NameNode)。
任何时候,只有一个名称节点是活动的,只有这个节点提供服务,而另一个处于待机状态。为了使这两个节点同步,它们需要通过高可用的共享存储实现编辑日记(editLog)的共享,当活动节点对命名空间进行任何修改,它也会把修改记录到日记文件,备用节点会监听这个文件,进行同步。
这时我们的DataNode就需要同时向两个名称节点发送数据块的处理报告了,才能保证备用节点有最新的集群中块信息。
如果活动的名称节点出现故障,会有特定的机制来处理,这一过程对用户是透明的。
回顾一下我们在上一篇博客中提到的HDFS1.0中的冷备份方法:第二名称节点secondaryNameNode。它的工作原理是怎样的呢,secondaryNameNode会定期地与NameNode通信,从名称节点上获取FSImage和EditLog文件,下载到本地的相应文件。执行EditLog和FSImage文件合并。然后将新的FSImage发送到名称节点上,替换旧的名称节点的FSImage,合并期间发生的新的操作都写在了名称节点上一个新生成的EditLog上去了。通过这种操作,缩小EditLog的大小,如果名称节点出现故障后,日记文件过大,这个恢复过程就需要很久。所以说,第二名称节点最主要的作用是防止日记文件越来越大。当然如果名称节点丢失FSImage,第二名称节点这里确实是还有一个合并过的FSImage文件的,这时候是可以顶替上去用的,但是这只是一个附带的作用。
HA方案解决的是单点故障问题,而Fdederation解决的是单命名空间问题。
集群的全部元数据都存放在一个名称节点上,当集群足够大的时候,这个名称节点就成了性能的瓶颈。而且这种设计不能进行 的隔离,用户的所有操作都必须由这一个节点来处理。
HDFS Federation就是使HDFS支持多个命名空间,并且允许在HDFS中同时存在多个NameNode。
单个NameNode的HDFS包括以下两层结构:
NameSpace管理目录,文件和数据块,支持常见的文件操作如创建、修改、删除。
Block Storage由两部分组成:
Blog Storage的这两部分分别在NameNode和DataNode上实现。
从图中我们看到NameSpace和Block Management是紧耦合的,这种紧密耦合的关系会导致实现另一套NameNode比较困难,也限制了其它想要直接使用块存储的应用。
HDFS的底层存储是可以水平扩展的,即数据节点通过添加机器就可以增加,但是NameSpace不可以,Namenode中存储整个分布式文件系统中的元数据信息,这限制 了集群中的数据块、文件和目录的数目。
Federation是简单健壮的设计,其对NameNode的改动很少,主要改变的是DataNode、config和Tools。
HDFS Federation的构架如上,其使用了多个独立的NameNode/NameSpace,从而使HDFS的命名服务器能水平扩张。
各个名称节点之间是联合的,即他们相互独立且不需要相互协调,各自分工,管理好自己的区域。分布式的DataNode对联合的NameNode来说是通用的数据块存储设备。每个数据节点要向所有的名称节点注册,并且周期性发送心跳和块信息报告,同时处理来自所有NameNode的指令。
只有一个名称节点的HDFS只有一个命名空间,它使用全部的块,而Federation中有多个独立的命名空间,每个命名空间使用一个块池(block pool)。
块池就是属于单个命名空间的一组块。每一个datanode为所有的block pool的存储块。dataNode是一个物理概念而block pool是一个重新将块划分的逻辑概念。同个dataNode中可以存着属于多个block pool的多个块。block pool允许一个命名空间在不通知其它命名空间的情况下为一个新的block创建Block ID,同时,一个nameNode的失效不会影响其下的dataNode为其它nameNode服务。
当datanode与Namenode建立联系并开始会话后自动建立Block pool。每个block都有一个唯一的标识,这个标识我们称之为扩展的块ID(Extended Block ID)= BlockID+BlockID。这个扩展的块ID在HDFS集群之间都是唯一的,这为以后集群归并创造了条件。
Datanode中的数据结构都通过块池ID(BlockPoolID)索引,即datanode中的BlockMap,storage等都通过BPID索引。
在HDFS中,所有的更新、回滚都是以Namenode和BlockPool为单元发生的。即同一HDFS Federation中不同的Namenode/BlockPool之间没有什么关系。
需要注意的是,HDFS Federation并不能解决单点故障问题。也就是说,每个名称节点仍然可能存在单点故障,节点间是联盟关系而非互为备份。因此,我们还是需要为每个节点设置ha机制。
多命名空间的管理用的是一种叫client side mount table的方法。
如下面的图所示,白色大三角形是客户端所看到的,黑色三角形是各个子命名空间。用户可以通过访问不同挂载点来访问不同空间。