1. 程式人生 > >三臺PC伺服器部署Hadoop HA(Hadoop 高可用性架構)

三臺PC伺服器部署Hadoop HA(Hadoop 高可用性架構)

寫在前邊的話:

        之前是在自己電腦上部署的hadoop叢集,但並未涉及到HA配置,這次將叢集遷移到PC伺服器,但是問題來了,只有三臺,但是我還想配置HA,PC伺服器是CentOS6.5,原來想著在上邊部署VM,從而部署HA叢集,但經測試,未果,遂棄之,就想到了在三臺機器上部署HA叢集。

hadoop偽分佈部署參考:點選開啟連結
         hadoop單機版部署參考:點選開啟連結
         zookeeper,hive,hbase的分散式部署參考:點選連結
         Spark,Sqoop,Mahout的分散式部署參考:點選連結

         步驟和部署hadoop叢集(

點選閱讀)是一樣的,只是這裡加入了HA的一些配置,記錄如下

一:架構說明

     IP                            hostname               role

    192.168.132.27       master1                  主節點

    192.168.132.28       master2                  備份主節點

    192.168.132.29       slaver1                    從節點

    zookeeper的三個節點叢集,部署在這三臺機子上

二:部署Zookeeper

       Hadoop HA的部署依賴於ZK來切換主節點,所以在部署Hadoop HA之前需要先把Zookeeper叢集搞定,部署參考:點選閱讀

三:部署HA

1:檔案配置

       除了配置檔案mapred-site.xml,core-site.xml,hdfs-site.xml,yarn-site.xml之外和hadoo叢集部署一樣,這裡不做陳述,可參考:點選閱讀

       mapred-site.xml:

<configuration>
  <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
  </property>
</configuration>

       core-site.xml:

<configuration>
  <!-- 指定hdfs的nameservice為ns -->
  <property>    
      <name>fs.defaultFS</name>    
      <value>hdfs://master</value>    
      <!--1.x中為fs.default.name, 一定得是namenode的hostname或者 ip,並且不用加埠號(這裡的名稱與HA配置hdfs-site.xml中的dfs.nameservices必須保持一致) -->  
  </property>
 
  <property>  
    <name>hadoop.tmp.dir</name>  
    <value>/opt/bigdata/hadoop/tmp</value>  
    <!-- 指定hadoop臨時目錄 -->
  </property>   

  <!-- 配置HA時才用配置該項 -->
  <property>
    <name>ha.zookeeper.quorum</name>
    <value>master1:2181,master2:2181,slaver1:2181</value>
    <!--各個ZK節點的IP/host,及客戶端連線ZK的埠,該埠需與zoo.cfg中的 clientPort一致! -->
  </property>
</configuration>

       hdfs-site.xml:

<configuration>
<property>  
    <name>dfs.replication</name>  
    <value>2</value>  
  </property>  
  <property>  
    <name>dfs.namenode.name.dir</name>  
    <value>file:///opt/bigdata/hadoop/dfs/name</value>  
  </property>  
  <property>  
    <name>dfs.datanode.data.dir</name>  
    <value>file:///opt/bigdata/hadoop/dfs/data</value>  
  </property>  
  <property>
    <name>dfs.webhdfs.enabled</name>
    <value>true</value>
    <!-- 在NN和DN上開啟WebHDFS (REST API)功能,不是必須 --> 
  </property>

  <!-- HA配置需要加如下配置-->
  <property>
    <name>dfs.nameservices</name>
    <value>master</value>
    <!--給hdfs叢集起名字,這個名字必須和core-site中的統一,且下面也會用到該名字,需要和core-site.xml中的保持一致 -->
  </property>

  <property>
    <name>dfs.ha.namenodes.master</name>
    <value>nn1,nn2</value>
    <!-- master1下面有兩個NameNode,分別是nn1,nn2,指定NameService是cluster1時的namenode有哪些,這裡的值也是邏輯名稱,名字隨便起,相互不重複即可 -->
  </property>

  <property>
    <name>dfs.namenode.rpc-address.master.nn1</name>
    <value>master1:9000</value>
    <!-- nn1的RPC通訊地址 -->
  </property>

  <property>
    <name>dfs.namenode.rpc-address.master.nn2</name>
    <value>master2:9000</value>
    <!-- nn2的RPC通訊地址 -->
  </property>

  <property>
    <name>dfs.namenode.http-address.master.nn1</name>
    <value>master1:50070</value>
    <!-- nn1的http通訊地址 -->
  </property>
  <property>
    <name>dfs.namenode.http-address.master.nn2</name>
    <value>master2:50070</value>
    <!-- nn2的http通訊地址 -->
  </property>

  <property>
    <name>dfs.namenode.servicerpc-address.master.nn1</name>
    <value>master1:53310</value>
  </property>

  <property>
    <name>dfs.namenode.servicerpc-address.master.nn2</name>
    <value>master2:53310</value>
  </property>

  <property>
    <name>dfs.namenode.shared.edits.dir</name>
    <value>qjournal://master1:8485;master2:8485;slaver1:8485/master</value>
    <!-- 指定NameNode的元資料在JournalNode上的存放位置 -->
  </property> 

  <property>
    <name>dfs.journalnode.edits.dir</name>
    <value>/opt/bigdata/hadoop/dfs/jndata</value>
    <!-- 指定JournalNode在本地磁碟存放資料的位置 -->
  </property>

  <property>
    <name>dfs.ha.automatic-failover.enabled</name>  
    <value>true</value>
    <!-- 開啟NameNode失敗自動切換 -->
  </property>

  <property>
    <name>dfs.client.failover.proxy.provider.master</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    <!-- 配置失敗自動切換實現方式 -->
  </property>

  <property>
    <name>dfs.ha.fencing.methods</name>
    <value>
      sshfence
      shell(/bin/true)
    </value>
    <!-- 配置隔離機制方法,多個機制用換行分割,即每個機制暫用一行-->
  </property>

  <property>
    <name>dfs.ha.fencing.ssh.private-key-files</name>
    <value>/root/.ssh/id_rsa</value>
    <!-- 使用sshfence隔離機制時需要ssh免登陸 -->
  </property>

  <property>
    <name>dfs.ha.fencing.ssh.connect-timeout</name>
    <value>3000</value>
    <!-- 配置sshfence隔離機制超時時間 -->
  </property>

</configuration>

       yarn-site.xml:

<configuration>

<!-- Site specific YARN configuration properties -->

  <property>
    <name>yarn.resourcemanager.ha.enabled</name>
    <value>true</value>
    <!-- 開啟RM高可用 -->
  </property>
  
  <property>
    <!--啟動自動故障轉移,預設為false-->
    <name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
    <value>true</value>
  </property>

  <property>
    <!--啟用一個內嵌的故障轉移,與ZKRMStateStore一起使用。-->
    <name>yarn.resourcemanager.ha.automatic-failover.embedded</name>
    <value>true</value>
  </property>
 
  <property>
    <name>yarn.resourcemanager.cluster-id</name>
    <value>yrc</value>
    <!-- 指定RM的cluster id -->
  </property>

  <property>
    <name>yarn.resourcemanager.ha.rm-ids</name>
    <value>rm1,rm2</value>
    <!-- 指定RM的名字 -->
  </property>
 
  <property>
    <name>yarn.resourcemanager.hostname.rm1</name>
    <value>master1</value>
    <!-- 分別指定RM的地址 -->
  </property>
  
  <property>
    <name>yarn.resourcemanager.hostname.rm2</name>
    <value>master2</value>
    <!-- 分別指定RM的地址 -->
  </property>

  <property>
    <name>yarn.resourcemanager.ha.id</name>
    <value>rm1</value>     
    <!--如果是在主NN上 這裡寫rm1   如果這個配置檔案是在備NN上 這裡寫rm2,否則RM的高可用會出問題-->
    <description>If we want to launch more than one RM in single node, we need this configuration</description>
  </property> 

  <property>  
    <name>yarn.resourcemanager.recovery.enabled</name>  
    <value>true</value>  
  </property>  

  <property>  
    <name>yarn.resourcemanager.store.class</name>  
    <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>  
  </property>    

  <property>
    <name>yarn.resourcemanager.zk-address</name>
    <value>master1:2181,master2:2181,slaver1:2181</value>
    <!-- 指定zk叢集地址 -->
  </property>

  <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
  </property>

</configuration>

 2:啟動服務,測試NameNode的自動切換

       PS:一定要注意啟動的順序,否則會出現各種各樣的錯誤,親測

       每臺機器上啟動Zookeeper:bin/zkServer.sh start 

       zookeeper叢集格式化(任意一個主節點上執行即可):bin/hdfs zkfc -formatZK

       每臺機器上啟動 journalnode:sbin/hadoop-daemon.sh start journalnode (如果這裡不啟動的話,在進行hdfs格式化的時候就會報錯,同時這個程序只需在格式化的時候啟動,後續啟動服務則不需要)

       hdfs叢集格式化(master1上進行):bin/hadoop namenode -format

看到 “0” 表示成功了

       

       master1機器上啟動服務:sbin/start-dfs.sh      sbin/start-yarn.sh

執行jps檢視進行如下(master1,master2,slaver1):

            

       master1(192.168.132.27)的web介面顯示如下:

       

         備用NN同步主NN的元資料資訊(master2上執行): bin/hdfs namenode -bootstrapStandby

         啟動備用NN(master2上執行): sbin/hadoop-daemon.sh start namenode

         執行jps(master2上執行):

         

         Web訪問:


         測試主NN和備用NN的切換:kill掉主NN程序  kill namenode_id

         再次重新整理master2對應的web,實現自動切換:

    

3:測試Resourcemanager自動切換

              訪問主NN的8088埠如下:

    

            備用NN的8088埠:

      

       kill 掉主NN的resourcemanager服務再次訪問從NN的8088埠

       

        OK!大功告成

四:遇見的問題

1:NameNode格式化失敗

            錯誤:failed on connection exception: java.net.ConnectException: Connection refused

            解決辦法:先啟動Zookeeper叢集,在用sbin/hadoop-daemon.sh start journalnode 啟動各個NameNode上的JournalNode程序,然後再進行格式化

            該錯誤參考部落格:http://blog.csdn.net/u014729236/article/details/44944773

     2:Web顯示live nodes 為 0

       

        解決辦法:註釋掉機子上 hosts檔案中的原本的兩行

        

3:master2的NameNode和 ResourceManager不能啟動

          檢視日誌發現錯誤
2016-08-30 06:10:57,558 INFO org.apache.hadoop.http.HttpServer2: HttpServer.start() threw a non Bind IOException
java.net.BindException: Port in use: master1:8088
        at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:919)
        at org.apache.hadoop.http.HttpServer2.start(HttpServer2.java:856)
        at org.apache.hadoop.yarn.webapp.WebApps$Builder.start(WebApps.java:274)
        at org.apache.hadoop.yarn.server.resourcemanager.ResourceManager.startWepApp(ResourceManager.java:974)
        at org.apache.hadoop.yarn.server.resourcemanager.ResourceManager.serviceStart(ResourceManager.java:1074)
        at org.apache.hadoop.service.AbstractService.start(AbstractService.java:193)
        at org.apache.hadoop.yarn.server.resourcemanager.ResourceManager.main(ResourceManager.java:1208)
Caused by: java.net.BindException: Cannot assign requested address
        at sun.nio.ch.Net.bind0(Native Method)
        at sun.nio.ch.Net.bind(Net.java:444)
        at sun.nio.ch.Net.bind(Net.java:436)
        at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
        at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
        at org.mortbay.jetty.nio.SelectChannelConnector.open(SelectChannelConnector.java:216)
        at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:914)
        ... 6 more
          埠被佔用了,這時候要修改yarn-site.xml 中
 <property>
    <name>yarn.resourcemanager.ha.id</name>
    <value>rm2</value>
    <description>If we want to launch more than one RM in single node, we need this configuration</description>
  </property>
         此時再次啟動OK

      4:NameNode不能自動切換

           hdfs-site.xml通過dfs.ha.fencing.methods控制自動切換的方法, sshfence是系統預設的並不能自動切換,這裡可以換成
<property>
    <name>dfs.ha.fencing.methods</name>
    <value>shell(/bin/true)</value>
    <!-- 配置隔離機制方法,多個機制用換行分割,即每個機制暫用一行-->
  </property>

五:總結

       在配置的過程中遇到了很多問題,參考了很多資料,但很多事情就是看著別人很順利的完成,可是到了你這裡就會出現各種錯誤,殊不知別人也是經歷過各種除錯才出的結果,所以不要灰心,在配置的過程中多看看日誌,所有的錯誤都會在日誌中顯示,相信你會成功的。