hadoop2.x通过Zookeeper来实现namenode的HA方案以及ResourceManager单点故障的解决方案

我们知道hadoop1.x之前的namenode存在两个主要的问题:1、namenode内存瓶颈的问题,2、namenode的单点故障的问题。针对这两个问题,hadoop2.x都对它进行改进和解决。其中,问题1中对namenode内存瓶颈的问题采用扩展namenode的方式来解决。对于问题2中的namenode的单点故障问题hadoop2.x采用的是HA的解决方案。apache hadoop 官方网站上提供了两种解决HDFS High Availability Using the Quorum Journal Manager 和High Availability with NFS。

  本文是采用HDFS High Availability Using the Quorum Journal Manager 方案来实现HA。并且实现namenode单点故障自动切换的功能,这就需要借助与zookeeper集群来实现。下面详细的讲解一下通过zookeeper来实现HDFS High Availability Using the Quorum Journal Manager 单点故障自动切换的方案。

  在介绍之前,首先说明一下我的集群规模:2个namenode(hadoop1,hadoop5),3个datanode(hadoop2,hadoop3,hadoop4)。

  ------------------------------------------------------------------------------------------------

  |        IP地址        |  主机名    | NameNode |  journalNode | DataNode | zookeeper |

  |  192.168.1.21   | hadoop1 |     是    |  是    |  否   |  是   |

  |  192.168.1.22   | hadoop2 |     否    |  是    |  是   |  是   |

  |  192.168.1.23   | hadoop3 |     否    |  是    |  是   |  是   |

  |  192.168.1.24   | hadoop4 |     否    |  是    |  是   |  是   |

  |  192.168.1.25   | hadoop5 |     是    |  是    |  否   |  是   |

  --------------------------------------------------------------------------------------------------

1、首先当然是安装zookeeper的集群了

  对于该集群的安装可以参考另一篇文章: http://www.cnblogs.com/ljy2013/p/4510143.html 。这篇文章详细介绍了zookeeper的安装

2、安装好了zookeeper集群之后,下一步就需要部署你自己的hadoop2.x的集群了。

  对于hadoop2.x的集群,我部署的是hadoop2.6.0的集群,部署方法可以参考文章:http://www.cnblogs.com/ljy2013/articles/4345172.html 。这篇文章当中详细介绍了如何安装和部署简单的hadoop的集群。

3、这里对journalnode进行说明一下,这个节点是一个轻量级的进行,可以与hadoop的集群部署在同一台机器上,并且,它的部署只需要添加hadoop相应的配置参数即可。

4、修改hadoop集群的配置文件,这里需要修改的配置文件较多,修改的参数更多,并且比较重要。

  (1)修改core-site.xml文件







<configuration>
    <property>
          <name>fs.defaultFSname>
          <value>hdfs://myclustervalue>
    property>
    <property>    
              <name>ha.zookeeper.quorumname>    
              <value>hadoop1:2181,hadoop2:2181,hadoop3:2181,hadoop4:2181,hadoop5:2181value>   
       property>

        <property>
          <name>ha.zookeeper.session-timeout.msname>
          <value>60000value>
        property>
        <property>
          <name>ha.failover-controller.cli-check.rpc-timeout.msname>
          <value>60000value>
        property>
        <property>
          <name>ipc.client.connect.timeoutname>
          <value>20000value>
        property>

configuration>2)修改hdfs-site.xml文件







<configuration>
    <property>
      <name>dfs.nameservicesname>
      <value>myclustervalue>
    property>
    <property>
      <name>dfs.ha.namenodes.myclustername>
      <value>nn1,nn2value>
    property>
    <property>
      <name>dfs.namenode.rpc-address.mycluster.nn1name>
     <value>hadoop1:9000value>
    property>
    <property>
      <name>dfs.namenode.rpc-address.mycluster.nn2name>
      <value>hadoop5:9000value>
    property>
    <property>
      <name>dfs.namenode.http-address.mycluster.nn1name>
       <value>hadoop1:50070value>
    property>
    <property>
      <name>dfs.namenode.http-address.mycluster.nn2name>
      <value>hadoop5:50070value>
    property>
    <property>
       <name>dfs.namenode.servicerpc-address.mycluster.nn1name>
       <value>hadoop1:53310value>
    property>
    <property>
       <name>dfs.namenode.servicerpc-address.mycluster.nn2name>
       <value>hadoop5:53310value>
    property>
    <property>  
       <name>dfs.ha.automatic-failover.enabledname>  
       <value>truevalue>  
    property> 
    <property>
      <name>dfs.namenode.shared.edits.dirname>
      <value>qjournal://hadoop1:8485;hadoop2:8485;hadoop3:8485;hadoop4:8485;hadoop5:8485/myclustervalue>
    property>
     <property>
    <name>dfs.journalnode.edits.dirname>
    <value>/home/grid/hadoop-2.6.0/journal/datavalue>
     property>
    <property>
      <name>dfs.client.failover.proxy.provider.myclustername>
      <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvidervalue>
    property>
    <property>
        <name>dfs.replicationname> 
        <value>3value>
    property>
    <property>
        <name>dfs.namenode.name.dirname>       
        <value>file:///home/grid/hadoop-2.6.0/dfs/namevalue>
    property>
    <property>
        <name>dfs.datanode.data.dirname>
        <value>file:///home/grid/hadoop-2.6.0/dfs/datavalue>
    property>
    <property>
        <name>dfs.webhdfs.enabledname>
        <value>truevalue>
    property> 
    <property>
    <name>dfs.permissions.enablename>
    <value>falsevalue>
    property>
    <property>
       <name>dfs.permissionsname>
       <value>falsevalue>
    property>
    <property>
       <name>dfs.image.transfer.bandwidthPerSecname>
       <value>1048576value>
    property>
    <property>
      <name>dfs.ha.fencing.methodsname>
      <value>shell(/bin/true)value>
    property>

configuration>
  
在这个文件中需要说明的有两点:

  第一、在官网上,我查看了hdfs-default.xml文件中,并没有参数dfs.ha.fencing.methods 这个参数,范围这个参数是在core-default.xml文件中有,那么按照官网上的意思是dfs.ha.fencing.methods 这个参数的配置是通过core-site.xml文件来设置的。但是实际上,这个参数是需要在hdfs-site.xml文件中设置的。否则就会出错,错误就是hadoop-daemon.sh start zkfc 启动DFSZKFailoverController进程时,无法启动。

  第二、官网上都是通过设置下面两个参数来实现,出现故障时,通过哪种方式登录到另一个namenode上进行接管工作。如果采用下面的参数的话,我设置集群就会报错。显示错误信息的是无法连接,也就是梁一个namenode连接被拒绝了。

        <property>
          <name>dfs.ha.fencing.methodsname>
          <value>sshfencevalue>
        property>

        <property>
          <name>dfs.ha.fencing.ssh.private-key-filesname>
          <value>/home/grid/.ssh/id_rsa_nnvalue>
        property>
所以,我换用了另一个值,如下:
    <property>
      <name>dfs.ha.fencing.methodsname>
      <value>shell(/bin/true)value>
    property>
  此时针对HDFS的HA的配置工作已经完成,对应的yarn-site.xml和mapred-site.xml可以采用 http://www.cnblogs.com/ljy2013/articles/4345172.html 一文中的方式来设置即可。在这里我还设置了ResourceManager进行了热备。于是我的文件如下:
(3)Yarn-site.xml文件的修改,该文件的配置对于不同的机器需要做出相应的修改工作。


<configuration>



    <property>
                <name>yarn.resourcemanager.connect.retry-interval.msname>
                <value>60000value>
        property>
        <property>
                <name>yarn.resourcemanager.ha.enabledname>
                <value>truevalue>
        property>
        <property>
                <name>yarn.resourcemanager.cluster-idname>
                <value>rm-clustervalue>
        property>
        <property>
                <name>yarn.resourcemanager.ha.rm-idsname>
                <value>rm1,rm2value>
        property>
        <property>
                <name>yarn.resourcemanager.ha.idname>   //不同的节点只需要对这个参数做出相应的修改即可,也就是在热备的另一个节点上,该参数设置为rm2.即两个备份机器上的yarn-site.xml文件就是该参数不同。
                <value>rm1value>
        property>
        <property>
                <name>yarn.resourcemanager.hostname.rm1name>
                <value>hadoop1value>
        property>
        <property>
                <name>yarn.resourcemanager.hostname.rm2name>
                <value>hadoop5value>
        property>
        <property>
                <name>yarn.resourcemanager.recovery.enabledname>
                <value>truevalue>
        property>
        <property>
                <name>yarn.resourcemanager.store.classname>
                <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStorevalue>
        property>
        <property>
                <name>yarn.resourcemanager.zk-addressname>
                <value>hadoop1:2181,hadoop2:2181,hadoop3:2181,hadoop4:2181,hadoop5:2181value>
        property>
        <property>
                <name>yarn.resourcemanager.address.rm1name>
                <value>${yarn.resourcemanager.hostname.rm1}:23140value>
        property>
        <property>
                <name>yarn.resourcemanager.scheduler.address.rm1name>
                <value>${yarn.resourcemanager.hostname.rm1}:23130value>
        property>
        <property>
                <name>yarn.resourcemanager.webapp.https.address.rm1name>
                <value>${yarn.resourcemanager.hostname.rm1}:23189value>
        property>
        <property>
                <name>yarn.resourcemanager.webapp.address.rm1name>
                <value>${yarn.resourcemanager.hostname.rm1}:23188value>
        property>
        <property>
                <name>yarn.resourcemanager.resource-tracker.address.rm1name>
                <value>${yarn.resourcemanager.hostname.rm1}:23125value>
        property>
        <property>
                <name>yarn.resourcemanager.admin.address.rm1name>
                <value>${yarn.resourcemanager.hostname.rm1}:23141value>
        property>

        <property>
                <name>yarn.resourcemanager.address.rm2name>
                <value>${yarn.resourcemanager.hostname.rm2}:23140value>
        property>
        <property>
                <name>yarn.resourcemanager.scheduler.address.rm2name>
                <value>${yarn.resourcemanager.hostname.rm2}:23130value>
        property>
        <property>
                <name>yarn.resourcemanager.webapp.https.address.rm2name>
                <value>${yarn.resourcemanager.hostname.rm2}:23189value>
        property>
        <property>
                <name>yarn.resourcemanager.webapp.address.rm2name>
                <value>${yarn.resourcemanager.hostname.rm2}:23188value>
        property>
        <property>
                <name>yarn.resourcemanager.resource-tracker.address.rm2name>
                <value>${yarn.resourcemanager.hostname.rm2}:23125value>
        property>
        <property>
                <name>yarn.resourcemanager.admin.address.rm2name>
                <value>${yarn.resourcemanager.hostname.rm2}:23141value>
        property>
        <property>
                <name>yarn.nodemanager.local-dirsname>
                <value>/home/hadoop/logs/yarn_localvalue>
        property>
        <property>
                <name>yarn.nodemanager.log-dirsname>
                <value>/home/hadoop/logs/yarn_logvalue>
        property>
        <property>
                <name>yarn.nodemanager.remote-app-log-dirname>
                <value>/home/hadoop/logs/yarn_remotelogvalue>
        property>
        <property>
                <name>yarn.log-aggregation-enablename>
                <value>truevalue>
        property>
        <property>
                <name>yarn.nodemanager.resource.memory-mbname>
                <value>2048value>
        property>
        <property>
                <name>yarn.nodemanager.vmem-pmem-rationame>
                <value>4.2value>
        property>
        <property>
                <name>yarn.nodemanager.resource.cpu-vcoresname>
                <value>2value>
        property>
        <property>
                <name>yarn.nodemanager.aux-servicesname>
                <value>mapreduce_shufflevalue>
        property>
        <property>
                <name>yarn.nodemanager.aux-services.mapreduce.shuffle.classname>
                <value>org.apache.hadoop.mapred.ShuffleHandlervalue>
        property>
configuration>4)mapred-site.xml文件的修改






<configuration>
    <property>
        <name>mapreduce.framework.namename>
        <value>yarnvalue>
    property>
    <property>
        <name>mapreduce.jobhistory.addressname>
        <value>hadoop1:10020,hadoop5:10020value>
    property>
    <property>
        <name>mapreduce.jobhistory.webapp.addressname>
        <value>hadoop1:19888,hadoop5:19888value>
    property>
    <property>
        <name>yarn.app.mapreduce.am.staging-dirname>
        <value>/tmp/hadoop-yarn/stagingvalue>
    property>
    <property>
    <name>mapreduce.jobhistory.done-dirname>
    <value>${yarn.app.mapreduce.am.staging-dir}/history/donevalue>
    property>
    <property>
        <name>mapreduce.jobhistory.intermediate-done-dirname>
        <value>${yarn.app.mapreduce.am.staging-dir}/history/done_intermediatevalue>
    property>
    <property>
        <name>mapreduce.task.io.sort.factorname>
        <value>100value>
    property>
    <property>
        <name>mapreduce.reduce.shuffle.parallelcopiesname>
        <value>10value>
    property>
configuration>
Ok了!至此,所有的配置文件修改工作都完成了。下面就是介绍一下如何启动了
5、启动
  (1)首先启动zookeeper集群
  由于我的节点是5个,所以我是将所有的节点都用来作为zookeeper来作为zookeeper的集群。因此在各节点上执行如下命令即可。
        zkServer.sh start
  所有的节点都启动zookeeper服务之后,zookeeper集群就已经启动了。
  (2)对zookeeper集群进行格式化
    hdfs zkfc -formatZK
  (3)启动JournalNode进程,注意这个在第一次的时候必须要按照这个顺序执行。否则后面hdfs格式化不了。
    同样,我也是将所有的节点都作为了journalnode的节点,于是在所有的节点上执行下面的命令来启动journalnode。
      hadoop-daemon.sh  start journalnode
  (4)格式化hadoop的集群,注意,第一次格式化必须首先启动上面的journalnode进程。并且,hadoop格式化的执行在某一个namenode节点上进行,在这里我选择的是hadoop1上执行。
        hdfs  namenode -format mycluster
  (5)启动第(4)步格式化之后的namenode。
      也就是说在第(4)步上面格式化后的namenode节点上启动namenode进程。
        hadoop-daemon.sh start namenode
  (6)在另外一个namenode节点上按顺序执行如下两个命令来启动namenode进程。(本文中是hadoop5上执行)
      hdfs namenode -bootstrapStandby
      hadoop-daemon.sh start namenode
  (7)在一个namenode节点上执行一下两个命令启动所有的进程:
      start-dfs.sh
      start-yarn.sh
  (8)此时启动完之后,我们可以通过下面的命令来查看两个namenode的状态是否是standby或者是active
      hdfs haadmin -getServiceState nn1
      standby
      hdfs haadmin -getServiceState nn2
      active
    这里的nn1和nn2就是上面的配置文件中所设置的。nn1对应的就是hadoop1,nn2对应的就是hadoop5。
6、检验自动切换,通过kill active的namenode来验证namenode是否能自动切换。
  (1)通过上面步骤(8)查看到对应的那个namenode的状态是active,在该namenode节点上查看所有的进程。如下所示:


  (2)在active的namenode节点上,执行 kill -9 7048  。实际上这一步可以直接将该节点重启也可以。
  (3)在standby的namenode节点上查看其状态的改变。
     hdfs haadmin -getServiceState nn1 
   我们可以看到其对应的状态从standby的状态转变为active的状态了。
7、通过上传文件来检测HDFS的健康状态
  执行 :hadoop fs -put /hadoop-2.6.0/etc/hadoop/hdfs-site.xml /
  然后可以通过web查看hdfs-site.xml

8、测试在作业运行时,namendoe挂掉了是否能自动切换,并且还能正常执行作业?
准备一个2G的文件,我准备了一不电影zr.MP4,2.13G准备上传上HDFS中,在上传的过程中kill 掉active的namenode 查看最终的运行结果。
  通过在在standby的namenode节点上执行:hadoop fs -put zr.mp4 /  。
  在它执行的过程中,在active的namenode节点上执行:kill -9  7048  (这里的7048就是namenode进程ID)。在执行过程中,我们可以看到如下图所示:


通过上图可以看出,最终zr.mp4上传成功了。至此HDFS的HA方案已经完成。完全可以投入使用。

你可能感兴趣的:(hadoop2.x通过Zookeeper来实现namenode的HA方案以及ResourceManager单点故障的解决方案)