天天看點

Hadoop 2.8 的namenode 從單點向雙namenode的HA的更新過程,含wordcount驗證配置Hadoop檔案啟動指令測試驗證

原文位址點選此處

參考文章見本文末尾

本文的主機規劃如下所示(jdk、關閉防火牆、免密碼ssh登入這些就不在此多做介紹了)

編号 ip 主機名 用途 安裝軟體
1 192.168.122.10 xxCentosZero NameNode(active)、JournalNode Hadoop、zookeeper
2 192.168.122.11 xxCentosOne NameNode(standby)、JournalNode Hadoop、zookeeper
3 192.168.122.12 xxCentosTwo DataNode、JournalNode Hadoop、zookeeper
4 192.168.122.13 xxCentosThree DataNode Hadoop、zookeeper
5 192.168.122.14 xxCentosFour DataNode Hadoop、zookeeper

配置雙namenode的目的就是為了防錯,防止一個namenode挂掉資料丢失,具體原理本文不詳細講解,這裡隻說明具體的安裝過程。

Hadoop HA的搭建是基于Zookeeper的,關于Zookeeper的搭建可以檢視這裡 hadoop、zookeeper、hbase、spark叢集環境搭建 ,本文可以看做是這篇文章的補充。這裡講一下Hadoop配置安裝。

配置Hadoop檔案

需要修改的配置檔案在$HADOOP_HOME/etc/hadoop目錄下面,具體修改内容如下:

core-site.xml

<!-- 指定hdfs的nameservice為lw_ns-->
 <property>
      <name>fs.defaultFS</name>
      <value>hdfs://lw_ns</value>
 </property>
 <!--指定hadoop資料臨時存放目錄-->
 <property>
      <name>hadoop.tmp.dir</name>
      <value>/usr/local/hadoop/tmp</value>
 </property>

 <property>
      <name>io.file.buffer.size</name>
      <value>4096</value>
 </property>
 <!--指定zookeeper位址-->
 <property>
      <name>ha.zookeeper.quorum</name>
      <value>CentosZero:2181,CentosOne:2181,CentosTwo:2181,CentosThree:2181,CentosFour:2181</value>
 </property>
           

說明一下, core-site.xml中的fs.defaultFS鍵對應的值一定要和hdfs-site.xml中的dfs.nameservices鍵的值一緻

hdfs-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl" target="_blank" rel="external nofollow" ?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>
	<!-- 指定hdfs的nameservice為ns,需要和core-site.xml中的保持一緻 -->
	<property>
		<name>dfs.nameservices</name>
		<value>lw_ns</value>
	</property>
	<!-- ns下面有兩個NameNode,分别是 lw_nn_0 ,lw_nn_1 -->
	<property>
		<name>dfs.ha.namenodes.lw_ns</name>
		<value>lw_nn_0,lw_nn_1</value>
	</property>
	<!-- lw_nn_0 的RPC通信位址 -->
	<property>
		<name>dfs.namenode.rpc-address.lw_ns.lw_nn_0</name>
		<value>CentosZero:9000</value>
	</property>
	<!-- lw_nn_0 的http通信位址 -->
	<property>
		<name>dfs.namenode.http-address.lw_ns.lw_nn_0</name>
		<value>CentosZero:50070</value>
	</property>
	<!-- lw_nn_1 的RPC通信位址 -->
	<property>
		<name>dfs.namenode.rpc-address.lw_ns.lw_nn_1</name>
		<value>CentosOne:9000</value>
	</property>
	<!-- lw_nn_1 的http通信位址 -->
	<property>
		<name>dfs.namenode.http-address.lw_ns.lw_nn_1</name>
		<value>CentosOne:50070</value>
	</property>
	<!-- 20170526注釋掉原有的非高可用狀态下的通路位址。
	<property>
		<name>dfs.http.address</name>
		<value>CentosOne:50070</value>
	</property>
	<property>
		<name>dfs.namenode.secondary.http-address</name>
		<value>CentosOne:50090</value>
	</property>
	-->
	<!-- 指定NameNode的中繼資料在JournalNode上的存放位置 -->
	<property>
       <name>dfs.namenode.shared.edits.dir</name>
       <value>qjournal://CentosZero:8485;CentosOne:8485;CentosTwo:8485/lw_ns</value>
  </property>
  <!-- 指定JournalNode在本地磁盤存放資料的位置 -->
  <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/usr/local/hadoop/journal</value>
  </property>
  <!-- 開啟NameNode故障時自動切換 -->
  <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
  </property>
  <!-- 配置失敗自動切換實作方式 -->
  <property>
          <name>dfs.client.failover.proxy.provider.ns</name>
          <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
  </property>
  <!-- 配置隔離機制 -->
  <property>
           <name>dfs.ha.fencing.methods</name>
           <value>sshfence</value>
  </property>
  <!-- 使用隔離機制時需要ssh免登陸 -->
  <property>
          <name>dfs.ha.fencing.ssh.private-key-files</name>
          <value>/root/.ssh/id_rsa</value>
  </property>
  
  <!-- 目前節點為name節點時的元資訊存儲路徑.這個參數設定為多個目錄,那麼這些目錄下都儲存着元資訊的多個備份 -->
  <property>
      <name>dfs.namenode.name.dir</name>
      <value>file:///usr/local/hadoop/somedata/name</value>
  </property>
  <!-- 目前節點為data節點時的元資訊存儲路徑.這個參數設定為多個目錄,那麼這些目錄下都儲存着資料資訊的多個備份 -->
  <property>
      <name>dfs.datanode.data.dir</name>
      <value>file:///usr/local/hadoop/somedata/data</value>
  </property>
  
	<property>
		<name>dfs.replication</name>
		<value>2</value>
	</property>
	<property>
		<name>dfs.permissions.enabled</name>
        	<value>false</value>
	</property>
</configuration>
           

這裡要說明一下,dfs.namenode.name.dir和dfs.datanode.data.dir的寫法一定要加 file://。否則啟動會說路徑不合法

dfs.journalnode.edits.dir鍵的值儲存的是namenodeHA的nameService的資訊。所有啟動了journal程序的主機的該路徑下都會有内容

還一點就是,雖然上面定義了lw_nn_0和lw_nn_1,但是不代表0一定是alive,另一個一定是standby。啟動時,這兩個會随機産生一個alive

mapred-site.xml

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

yarn-site.xml

<!-- 指定nodemanager啟動時加載server的方式為shuffle server -->
    <property>
            <name>yarn.nodemanager.aux-services</name>
            <value>mapreduce_shuffle</value>
     </property>
     <property>
            <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
            <value>org.apache.hadoop.mapred.ShuffleHandler</value>
     </property>
     <!-- 指定resourcemanager位址 -->
     <property>
            <name>yarn.resourcemanager.hostname</name>
            <value>CentosOne</value>
      </property>
           

以上兩個配置是原作者的,我隻是修改了主機名,但是我的實際情況是,仍然使用我之前的非HA的配置方式,如下所示

mapred-site.xml

<configuration>
    <property>
        <name>mapred.job.tracker</name>
        <value>CentosOne:9001</value>
    </property>
    <property>
        <name>mapred.map.tasks</name>
        <value>20</value>
    </property>
    <property>
        <name>mapred.reduce.tasks</name>
        <value>4</value>
    </property>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>CentosOne:10020</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>CentosOne:19888</value>
    </property>
</configuration>
           

yarn-site.xml

<configuration>

<!-- Site specific YARN configuration properties -->
        <property>
                <name>yarn.resourcemanager.address</name>
                <value>CentosOne:8032</value>
        </property>
        <property>
                <name>yarn.resourcemanager.scheduler.address</name>
                <value>CentosOne:8030</value>
        </property>
        <property>
                <name>yarn.resourcemanager.webapp.address</name>
                <value>CentosOne:8088</value>
        </property>
        <property>
                <name>yarn.resourcemanager.resource-tracker.address</name>
                <value>CentosOne:8031</value>
        </property>
        <property>
                <name>yarn.resourcemanager.admin.address</name>
                <value>CentosOne:8033</value>
        </property>
        <property>
                <name>yarn.nodemanager.aux-services</name>
                <value>mapreduce_shuffle</value>
        </property>
        <property>
                <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
                <value>org.apache.hadoop.mapred.ShuffleHandler</value>
        </property>
</configuration>
           

hadoop-env.sh添加如下内容

export JAVA_HOME=/data/install/jdk
# ssh端口非預設22端口
export HADOOP_SSH_OPTS="-p 22022"
           

yarn-env.sh添加如下内容

export JAVA_HOME=/data/install/jdk
           

啟動指令

注意首次初始化啟動指令和之後啟動的指令是不同的,首次啟動比較複雜,步驟不對的話就會報錯,不過之後就好了

首次啟動指令

1、首先啟動各個節點的Zookeeper,在各個節點上執行以下指令:

bin/zkServer.sh start
           

2、在某一個namenode節點執行如下指令,建立命名空間

hdfs zkfc -formatZK
           

3、在每個journalnode節點用如下指令啟動journalnode

/usr/local/hadoop/sbin/hadoop-daemon.sh start journalnode
           

4、在主namenode節點用格式化namenode和journalnode目錄

hdfs namenode -format lwns
           

5、在主namenode節點啟動namenode程序

/usr/local/hadoop/sbin/hadoop-daemon.sh start namenode
           

6、在備namenode節點執行第一行指令,這個是把備namenode節點的目錄格式化并把中繼資料從主namenode節點copy過來,并且這個指令不會把journalnode目錄再格式化了!然後用第二個指令啟動備namenode程序!

hdfs namenode -bootstrapStandby
/usr/local/hadoop/sbin/hadoop-daemon.sh start namenode
           

7、在兩個namenode節點都執行以下指令

/usr/local/hadoop/sbin/hadoop-daemon.sh start zkfc
           

8、在所有datanode節點都執行以下指令啟動datanode

/usr/local/hadoop/sbin/hadoop-daemon.sh start datanode
           

日常啟停指令

./start-all.sh
./stop-all.sh
           

其實就是說,第一次啟動比較複雜,最好按照這個次序來,然後以後啟動,就可以随便在一個namenode上的/usr/local/hadoop/sbin/下執行上面的兩個腳本即可。

測試驗證

首先在浏覽器分别打開兩個節點的namenode狀态,其中一個顯示active,另一個顯示standby

Hadoop 2.8 的namenode 從單點向雙namenode的HA的更新過程,含wordcount驗證配置Hadoop檔案啟動指令測試驗證
Hadoop 2.8 的namenode 從單點向雙namenode的HA的更新過程,含wordcount驗證配置Hadoop檔案啟動指令測試驗證

殺掉active主機的程序

Hadoop 2.8 的namenode 從單點向雙namenode的HA的更新過程,含wordcount驗證配置Hadoop檔案啟動指令測試驗證

再檢視原來standby主機的狀态

Hadoop 2.8 的namenode 從單點向雙namenode的HA的更新過程,含wordcount驗證配置Hadoop檔案啟動指令測試驗證

2017-05-28:為了測試這樣更新後,是否還能執行mapreduce的功能。是以執行一下hadoop2.8自帶的wordcount例子驗證

建立input目錄

hadoop fs -mkdir /hadoop/input1
           

使用hadoop的根目錄下自帶的LICENSE.txt檔案測試

hadoop fs -put /usr/local/hadoop/LICENSE.txt /hadoop/input1
           

使用wordcount測試類進行處理測試

cd /usr/local/hadoop/share/hadoop/mapreduce/
ls  --檢視hadoop-mapreduce-examples-2.8.0.jar
hadoop jar hadoop-mapreduce-examples-2.8.0.jar wordcount /hadoop/input /hadoop/output
           

稍後會在/hadoop/output路徑下看到結果

hadoop fs -ls /hadoop/output
           
Hadoop 2.8 的namenode 從單點向雙namenode的HA的更新過程,含wordcount驗證配置Hadoop檔案啟動指令測試驗證

說明得到了執行結果,也說明HA的配置沒問題。驗證完畢

2017-05-31補充:

在目前這個配置及安裝的軟體環境下, 正常啟動後,各主機的程序應該是這樣的(各主機用途見文章開頭)

192.168.122.11執行

/usr/local/hadoop/sbin/start-all.sh

執行後的再執行jps時,應該是在active的NameNode上看到六個程序

1780 NameNode

1988 JournalNode

1590 QuorumPeerMain

2230 ResourceManager

2545 Jps

2138 DFSZKFailoverController

standby的NameNode上看到5個程序,比上面少了一個ResourceManager

另外三個DataNode上面,除了有一個作為JournalNode存在,會多一個JournalNode程序之外

都是隻有4個程序

1625 NodeManager

1564 DataNode

1800 Jps

1482 QuorumPeerMain

但是之前發現我的standby的NameNode上沒有DFZKFailoverController程序,

我以為需要在這個standby節點上做一次對zookeeper的格式化

後來我再次啟動的時候,發現在standby上自動出現了。這是我沒做格式化操作的情況下出現的

是以可能我之前的啟動不完全或者有什麼異常存在吧。

2017-06-02

部署zookeeper的伺服器不需要與hadoop一一對應。隻需要在core-site.xml和hdfs-site.xml這些配置檔案中關聯即可

在mapred-site.xml的最後,需要添加以下配置。作用見注釋

<!-- 配置historyserver。目的是在頁面上可以看任務執行的所有節點日志資訊彙總  -->
	<property>
		<name>mapreduce.jobhistory.address</name>
		<value>liweiCentosOne:10020</value>
	</property>
	<!-- 指定historyserver在web端通路位址,預設端口19888 -->
	<property>
		<name>mapreduce.jobhistory.webapp.address</name>
		<value>liweiCentosOne:19888</value>
	</property>
	<!-- 指定historyserver收集各節點日志後存放的資料路徑 -->
	<property>
		<name>mapreduce.jobhistory.intermediate-done-dir</name>
		<value>/usr/local/hadoop/tmp/mr-his</value>
	</property>
	<!-- 指定historyserver處理完畢各節點日志後存放的資料路徑 -->
	<property>
		<name>mapreduce.jobhistory.done-dir</name>
		<value>mkdir /usr/local/hadoop/tmp/mr-done</value>
	</property>
           

在yarn-site.xml最後加上如下内容,作用見注釋

<!-- 啟動historyserver收集各節點日志功能這樣才能在web端的通路位址上統一檢視日志  -->
	<property>
		<name>yarn.log-aggregation-enable</name>
		<value>true</value>
	</property>
           

2017-06-06:

如果需要重新格式化zk和NameNode,那麼JournalNode相應的東西一定要清除

這是因為:

1:這裡面儲存了原本該存儲于NameNode的tmp目錄下的VERSION檔案夾及其内容

2:原本NameNode在非HA的情況下,本該儲存在/usr/local/hadoop/tmp下面的東西,現在都由這個JournalNode來統一管理了。

2017-06-07:

昨天我因為處理hbase的異常,而重新格式化了hadoop和zookeeper之後,今天再執行/usr/local/hadoop/sbin/start-all.sh

發現CentosZero和CentosOne上都沒有DFSZKFailoverController程序

然後從網頁通路了一下這兩台伺服器,發現狀态都是standby。是否我昨天格式化的時候哪兒弄錯了,讓它們變成了需要手動切換狀态的樣子了呢?

有人說需要重新格式化zookeeper。我嘗試下看看

參考文章

1:zookeeper及NN的HA的實作原理及分析

繼續閱讀