HDFS1.0 与HDFS2.x 架构理解

 

 

先说说Haoop HDFS 1.0的体系架构:

HDFS1.0体系架构总体图:

                                             

                                                        

hadoop架构运维 hadoop1.0架构_hadoop

上面可以看到几个组件:

 

NameNode :

  NameNode 是分布式文件系统的管理者, 主要负责文件系统的命名空间,集群配置信息与存储块的复制, NameNode 将Meta-data信息存储在内存中,Meta-Data包含文件信息,和每个文件块的信息,与每个文件块在哪个DataNode信息

 

Secondary NameNode:

 辅助NameNode 不是 NameNode的热备,主要作用是分担NameNode工作量,定时合并fsimage和fsedits,推送给NameNode,紧急时可以帮助恢复NameNode,Editlog事务日志记录到fsedit ,根据Fsedit,更新印象文件fsimage(存储文件系统的命名空间,包含文件的映射与文件的属性等信息。

  1)、fsimage文件其实是Hadoop文件系统元数据的一个永久性的检查点,其中包含Hadoop文件系统中的所有目录和文件idnode的序列化信息;
   2)、edits文件存放的是Hadoop文件系统的所有更新操作的路径,文件系统客户端执行的所以写操作首先会被记录到edits文件中。

 fsimage包含Hadoop文件系统中的所有目录和文件idnode的序列化信息;对于文件来说,包含的信息有修改时间、访问时间、块大小和组成一个文件块信息等;而对于目录来说,包含的信息主要有修改时间、访问控制权限等信息。fsimage并不包含DataNode的信息,而是包含DataNode上块的映射信息,并存放到内存中,当一个新的DataNode加入到集群中,DataNode都会向NameNode提供块的信息,而NameNode会定期的“索取”块的信息,以使得NameNode拥有最新的块映射。因为fsimage包含Hadoop文件系统中的所有目录和文件idnode的序列化信息,所以如果fsimage丢失或者损坏了,那么即使DataNode上有块的数据,但是我们没有文件到块的映射关系,我们也无法用DataNode上的数据!所以定期及时的备份fsimage和edits文件非常重要!

 关于fsimage与Fsedit中的流程:

                

hadoop架构运维 hadoop1.0架构_hadoop_02

 

DataNode:

  保存文件的基本信息,他将Block存储在文件系统中,保存了Block的Meta-data,并且定时将Meta-Data信息,发送给NameNode

 

Client:

  与NameNode 交互获取文件位置信息,与DataNode交互,读取和写入文件。

   文件写入:

       1)Client向NameNode发起写请求,

       2)NameNode根据文件大小和文件配置情况返回给Client部分DataNode信息

       3)Client将文件划分成多个Bock ,根据DataNode的地址信息,按顺序写到每个DataNode中,

  文件读取:

      1)Client向NameNode发起读请求

       2) NameNode返回DataNode信息

      3)Client根据返回的信息去读取DataNode上数据信息。

 

总结:

 Hadoop 1.x优点:

              1)可以处理大文件  2)可以运行在廉价的集群上 

      缺点:

          NameNode单点故障,SecondaryNode单点故障,不能恢复,这个风险非常大。其次NameNode内存受限不好扩展,因为HDFS1.0架构中只有一个NameNode,并且管理所有的DataNode。

 

   Hadoop2.x 的系统架构:

      Hadoop 2.X为了解决1.0 的单点故障问题,与内存受限问题在架构方面进行改进,使用方式不变。

      Hadoop2.0采用了HA机制。 通过主备切换,解决NameNode单点故障问题

      Hadoop2.0采用了HDFS Federation,水平扩展,支持多个NameNode,NameNode分管一些目录,

      架构图如下:

               

hadoop架构运维 hadoop1.0架构_hadoop_03

还有一个类似的架构,供参考:

hadoop架构运维 hadoop1.0架构_Hadoop_04

   可以看到 这个架构体系包含的几个组件:

     1)对比HDFS1.x 没有Secondary NameNode组件了 JournalNodes替代了SecondaryNameNode, 

     2) 对比Hadoop1.0  HDFS2.x 多了 DFSZKFailoverController

     3)还有就是有ZK

 

DFSZKFailoverController

   DFSZKFailoverController是Hadoop2.7中的一个核心组件,继承于ZKFailoverController

   主要功能是在ZK上注册NameNode和监控NamaNode运行状态, NameNode古典后ZKFC为竞争锁,获得ZKFC的NameNode为Active其他为Standby

JournalNodes:

    JournaNodes集群负责与Standy NameNode 和Active NameNode通讯 ,替代了HDFS1.x中Secondary NameNode的工作,NameNode 上所有的edit信息都会存储到JournalNode集群上,在JournalNode节点上Fsimage根据Edit新建进行合并,并且将新的fsimage发送给StandyNameNode和Active NameNode, 一旦Active NameNode出现异常,Standby NameNode会从Jouranl读取所有的Edit信息,然后切换成Active.

 

关于HDFS2.X fsimage与Fsedit的处理:

HA模式下的edit log文件会同时写入多个JournalNodes节点的

 

 (1)、配置好HA后,客户端所有的更新操作将会写到JournalNodes节点的共享目录中,可以通过下面配置hdfs-site.xml

    (2)、Active Namenode和Standby NameNode从JournalNodes的edits共享目录中同步edits到自己edits目录中;

 (3)、Standby NameNode中的StandbyCheckpointer类会定期的检查合并的条件是否成立,如果成立会合并fsimage和edits文件;
 (4)、Standby NameNode中的StandbyCheckpointer类合并完之后,将合并之后的fsimage上传到Active NameNode相应目录中;
 (5)、Active NameNode接到最新的fsimage文件之后,将旧的fsimage和edits文件清理掉;
 (6)、通过上面的几步,fsimage和edits文件就完成了合并,由于HA机制,会使得Standby NameNode和Active NameNode都拥有最新的fsimage和edits文件(之前Hadoop 1.x的SecondaryNameNode中的fsimage和edits不是最新的)

 

<property>
  <name>dfs.namenode.shared.edits.dir</name>
  <value>qjournal://XXXX/mycluster</value>
</property>
 
<property>
  <name>dfs.journalnode.edits.dir</name>
  <value>/export1/hadoop2x/dfs/journal</value>
</property>

 

 

 

 

 

查看NameNode edit fsimage 文件:

 

Hdfs-site.xml中

配置有current目录

hadoop架构运维 hadoop1.0架构_hadoop_05

查看Current目录:

hadoop架构运维 hadoop1.0架构_hadoop_06

     

 

 为了解决NameNode可以水平扩展的问题:

Hadoop 2.x采用了

 HDFS Federation  

   同时部署多个NameNode,这些NameNode之间是相互独立,也就是说他们不需要相互协调,DataNode同时在所有NameNode中注册,作为他们共有的存储节点,并定时向所有的这些NameNode发送心跳块使用情况的报告,并处理所有NameNode向其发送的指令。该架构如图2所示:

    架构如下:

         

hadoop架构运维 hadoop1.0架构_hadoop架构运维_07

引入了两个概念 Bock Pool(存储块池)与ClusterID 集群ID

 

    ①一个Bock Pool 是块的集合,这些块属于一个单一的Namespace。DataNode存储着集群中所有Block Pool中的块。Block Pool的管理相互之间是独立的。这意味着一个Namespace可以独立的生成块ID,不需要与其他Namespace协调。一个NameNode失败不会导致Datanode的失败,这些Datanode还可以服务其他的Namenode。

  一个Namespace和它的Block Pool一起称作命名空间向量(Namespace Volume)。这是一个自包含单元。当一个NameNode/Namespace删除后,对应的Block Pool也会被删除。当集群升级时,每个Namespace Volume也会升级。

  ②集群ID(ClusterID)的加入,是用于确认集群中所有的节点,也可以在格式化其它Namenode时指定集群ID,并使其加入到某个集群中。

 (2)HDFS Federation与老HDFS架构的比较

①老HDFS架构只有一个命名空间(Namespace),它使用全部的块。而HDFS Federation 中有多个独立的命名空间(Namespace),并且每一个命名空间使用一个块池(block pool)。

②老HDFS架构中只有一组块。而HDFS Federation 中有多组独立的块。块池(block pool)就是属于同一个命名空间的一组块。

③老HDFS架构由一个Namenode和一组datanode组成。而HDFS Federation 由多个Namenode和一组Datanode,每一个Datanode会为多个块池(block pool)存储块。

 

 

 

看个配置文件就知道了Federation怎么配置了:

 

集群c1的文件hdfs-site.xml
该文件只配置在hadoop101和hadoop102上。

<configuration> 
    <property> 
        <name>dfs.replication</name> 
        <value>2</value> 
    </property>

【指定DataNode存储block的副本数量。默认值是3个,我们现在有4个DataNode,该值不大于4即可。】 
    <property> 
        <name>dfs.nameservices</name> 
        <value>cluster1,cluster2</value> 
    </property>

【使用federation时,使用了2个HDFS集群。这里抽象出两个NameService实际上就是给这2个HDFS集群起了个别名。名字可以随便起,相互不重复即可】 
    <property> 
        <name>dfs.ha.namenodes.cluster1</name> 
        <value>hadoop101,hadoop102</value> 
    </property>

【指定NameService是cluster1时的namenode有哪些,这里的值也是逻辑名称,名字随便起,相互不重复即可】 
    <property> 
        <name>dfs.namenode.rpc-address.cluster1.hadoop101</name> 
        <value>hadoop101:9000</value> 
    </property>

【指定hadoop101的RPC地址】 
    <property> 
        <name>dfs.namenode.http-address.cluster1.hadoop101</name> 
        <value>hadoop101:50070</value> 
    </property>

【指定hadoop101的http地址】 
    <property> 
        <name>dfs.namenode.rpc-address.cluster1.hadoop102</name> 
        <value>hadoop102:9000</value> 
    </property>

【指定hadoop102的RPC地址】

    <property> 
        <name>dfs.namenode.http-address.cluster1.hadoop102</name> 
        <value>hadoop102:50070</value> 
    </property>

【指定hadoop102的http地址】 
    <property> 
        <name>dfs.namenode.shared.edits.dir</name> 
        <value>qjournal://hadoop101:8485;hadoop102:8485;hadoop103:8485/cluster1</value> 
    </property> 
【指定cluster1的两个NameNode共享edits文件目录时,使用的JournalNode集群信息】

         <property> 
        <name>dfs.ha.automatic-failover.enabled.cluster1</name> 
        <value>true</value> 
    </property> 
【指定cluster1是否启动自动故障恢复,即当NameNode出故障时,是否自动切换到另一台NameNode】

    <property> 
        <name>dfs.client.failover.proxy.provider.cluster1</name> 
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> 
    </property>

【指定cluster1出故障时,哪个实现类负责执行故障切换】 
    <property> 
        <name>dfs.ha.namenodes.cluster2</name> 
        <value>hadoop103,hadoop104</value> 
    </property>

【指定NameService是cluster2时,两个NameNode是谁,这里是逻辑名称,不重复即可。以下配置与cluster1几乎全部相似,不再添加注释】 
    <property> 
        <name>dfs.namenode.rpc-address.cluster2.hadoop103</name> 
        <value>hadoop103:9000</value> 
    </property> 
    <property> 
        <name>dfs.namenode.http-address.cluster2.hadoop103</name> 
        <value>hadoop103:50070</value> 
    </property> 
    <property> 
        <name>dfs.namenode.rpc-address.cluster2.hadoop104</name> 
        <value>hadoop104:9000</value> 
    </property>

    <property> 
        <name>dfs.namenode.http-address.cluster2.hadoop104</name> 
        <value>hadoop104:50070</value> 
    </property> 
    <!-- 
    <property> 
        <name>dfs.namenode.shared.edits.dir</name> 
        <value>qjournal://hadoop101:8485;hadoop102:8485;hadoop103:8485/cluster2</value> 
    </property>