天天看點

【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援

1、HDFS 2.0 基本概念

相比于 Hadoop 1.0,Hadoop 2.0 中的 HDFS 增加了兩個重大特性,HA 和 Federaion。HA 即為 High Availability,用于解決 NameNode 單點故障問題,該特性通過熱備的方式為主 NameNode 提供一個備用者,一旦主 NameNode 出現故障,可以迅速切換至備 NameNode, 進而實作不間斷對外提供服務。Federation 即為“聯邦”,該特性允許一個 HDFS 叢集中存在 多個 NameNode 同時對外提供服務,這些 NameNode 分管一部分目錄(水準切分),彼此之 間互相隔離,但共享底層的 DataNode 存儲資源。

本文檔重點介紹 HDFS HA 的安裝部署方法。

2、HDFS HA 配置部署

在一個典型的 HDFS HA 場景中,通常由兩個 NameNode 組成,一個處于 active 狀态, 另一個處于 standby 狀态。Active NameNode 對外提供服務,比如處理來自用戶端的 RPC 請 求,而 Standby NameNode 則不對外提供服務,僅同步 active namenode 的狀态,以便能夠在 它失敗時快速進行切換。

為了能夠實時同步 Active 和 Standby 兩個 NameNode 的中繼資料資訊(實際上 editlog), 需提供一個共享存儲系統,可以是 NFS、QJM(Quorum Journal Manager)或者 Bookeeper, Active Namenode 将資料寫入共享存儲系統,而 Standby 監聽該系統,一旦發現有新資料寫 入,則讀取這些資料,并加載到自己記憶體中,以保證自己記憶體狀态與 Active NameNode 保持 基本一緻,如此這般,在緊急情況下 standby 便可快速切為 active namenode。

注意,在 Hadoop 2.0 中,不再需要 secondary namenode 或者 backup namenode,它們的 工作由 Standby namenode 承擔。

本文将重點介紹基于 QJM 的 HA 解決方案。在該方案中,主備 NameNode 之間通過一 組 JournalNode 同步中繼資料資訊,一條資料隻要成功寫入多數 JournalNode 即認為寫入成功。 通常配置奇數個(2N+1)個 JournalNode,這樣,隻要 N+1 個寫入成功就認為資料寫入成功, 此時最多容忍 N-1 個 JournalNode 挂掉,比如 3 個 JournalNode 時,最多允許 1 個 JournalNode 挂掉,5 個 JournalNode 時,最多允許 2 個 JournalNode 挂掉。基于 QJM 的 HDFS 架構如下 所示:

【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援

3. 環境說明

三台虛拟機,每台虛拟機安裝ubantu16.04。每台機器的名稱,IP位址,程序内容如下

主機名稱 作業系統 IP位址 使用者名 密碼 程序
master ubuntu16.04LTS 192.168.80.130 hadoop [email protected] NameNode,ResourceManager,JournalNode,QuorumPeerMain,DFSZKFailoverController,JobHistoryServer
host2 ubuntu16.04LTS 192.168.80.131 hadoop [email protected] NameNode,DataNode,ResourceManager,NodeManager,JournalNode,QuorumPeerMain,DFSZKFailoverController
host3 ubuntu16.04LTS 192.168.80.132 hadoop [email protected] NodeManager,DataNode,QuorumPeerMain,JournalNode

程序介紹:

NameNode:NameNode(管理者)

ResourceManager:YARN中的資料總管(Resource Manager)負責整個系統的資源管理和排程,并内 部維護了各個應用程式的ApplictionMaster資訊,NodeManager資訊,資源使用資訊等

DataNode:DataNode(工作者)

NodeManager:NodeManager(NM)是YARN中每個節點上的代理,它管理Hadoop叢集中單個計算節點,包括與ResourceManger保持通信,監督Container的生命周期管理,監控每個Container的資源使用(記憶體、CPU等)情況,追蹤節點健康狀況,管理日志和不同應用程式用到的附屬服務(auxiliary service)。

JournalNode:JournalNode是用于存儲hdfs中,NameNode的記錄檔(也就是edits)的,一般由單數個(3個以上)節點組成,保證對于edits的高可靠存儲

QuorumPeerMain:Zookeeper服務

DFSZKFailoverController:zookeeper用戶端,用于自動切換ActiveNameNode

JobHistoryServer:實作web檢視作業的曆史運作情況

4. 安裝包準備

需要上網下載下傳收集hadoop-2.7.0.tar.gz、jdk-1.7.tar.gz、zookeeper-3.4.6.tar.gz、jsch-0.1.54.jar

注意:jsch-0.1.54.jar用于替換hadoop-2.7.0.tar.gz中自帶的jsch-0.1.42.jar,以解決在自動備援中出現的連接配接錯誤,而無法實作自動備援。

【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援

5. 關閉防火牆

//切換到超級使用者

su root

//關閉防火牆

ufw disable

6. 安裝vim編輯器和ssh

//安裝vim編輯器

sudo apt-get install vim

//安裝ssh

sudo apt-get insatll ssh
           

//檢視ssh是否安裝成功

service  ssh status
           

//生成秘鑰,在所有機器上執行下指令生成公鑰。将所有公鑰放在一個檔案中。

ssh-keygen -t rsa
           

//進入ssh目錄

cd ~/.ssh   
           

//(把公鑰複制一份,并改名為authorized_keys,這步執行完,應該ssh localhost可以無密碼登入本機了,可能第一次要密碼)

cp id_rsa.pub authorized_keys
           

//修改authorized_keys權限

chmod  authorized_keys
           

注意:這三台機器生成的rsa.pub中的内容合并到authorized_keys中,然後将authorized_keys更新到每台機器的主目錄下的.ssh目錄中。以實作各台主機的不需要使用者名密碼登入。最後整合的authorized_keys如下圖

【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援

在master主機上使用指令

//首次使用會提示輸入使用者名和密碼,之後在使用就不用輸入使用者名和密碼了

ssh host2
           
【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援

7. 修改主機名和主機和IP映射清單

//修改主機名

sudo vim /etc/hostname

//修改主機名稱和IP位址清單

sudo vim /etc/hosts

8.安裝JDK

//将jdk解壓到/usr/lib檔案夾中

//進入目前目錄

cd /usr/lib 
           

//使用tar指令解壓jdk壓縮包

【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援

設定環境變量

sudo gedit ~/.bashrc

在最下面添加:

export JAVA_HOME=/usr/lib/jdk1.7.0_51 export PATH=$JAVA_HOME/bin:$PATH

使配置檔案生效

source ~/.bashrc讓

//檢視jdk是否安裝成功

java -version

【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援

9.安裝zookeeper

//進入/usr/local目錄

cd /usr/local 
sudo tar -zxvf ~/下載下傳/zookeeper-.tar.gz
sudo chown -R hadoop /usr/local/zookeeper-/
           

//設定環境變量

sudo gedit ~/.bashrc
export ZOOKEEPER_HOME=/usr/local/zookeeper-.
export PATH=$ZOOKEEPER_HOME/bin:$ZOOKEEPER_HOME/conf:$PATH
source ~/.bashrc
           

//建立zoo.cfg并修改

【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援

參數說明:

①tickTime:心跳時間,毫秒為機關。

②initLimit:這個配置項是用來配置 Zookeeper 接受用戶端(這裡所說的用戶端不是使用者連接配接 Zookeeper伺服器的用戶端,而是 Zookeeper 伺服器叢集中連接配接到 Leader 的 Follower 伺服器)初始化連接配接時最長能忍受多少個心跳時間間隔數。當已經超過 10 個心跳的時間(也就是 tickTime)長度後 Zookeeper 伺服器還沒有收到用戶端的傳回資訊,那麼表明這個用戶端連接配接失敗。總的時間長度就是 10*2000=20 秒。

③syncLimit:這個配置項辨別 Leader 與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 5*2000=10 秒。

④dataDir:存儲記憶體中資料庫快照的位置。

⑤clientPort:監聽用戶端連接配接的端口

⑥server.A=B:C:D:其中 A 是一個數字,表示這個是第幾号伺服器;B 是這個伺服器的 ip 位址;C 表示的是這個伺服器與叢集中的 Leader 伺服器交換資訊的端口;D 表示的是萬一叢集中的 Leader 伺服器挂了,需要一個端口來重新進行選舉,選出一個新的 Leader,而這個端口就是用來執行選舉時伺服器互相通信的端口。如果是僞叢集的配置方式,由于 B 都是一樣,是以不同的 Zookeeper 執行個體通信端口号不能一樣,是以要給它們配置設定不同的端口号。

5)dataDir目錄下建立myid檔案,将内容設定為上⑥中的A值,用來辨別不同的伺服器

cd /usr/local/zookeeper-./
mkdir tmp
cd tmp
touch myid
vim myid
           
【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援

10.安裝Hadoop

//将hadoop解壓到/usr/local檔案夾中

// 進入目前目錄

cd /usr/local
           

//使用tar指令解壓jdk壓縮包

注意:将jsch-0.1.42.jar替換為jsch-0.1.54.jar解決namenode節點無法切換問題,産生原因是openssh-server7與jsch-0.1.42.jar不相容。

【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援

//修改檔案權限

sudo chown -R hadoop /usr/local/hadoop-. 
           

//修改環境變量,将hadoop加進去

sudo gedit ~/.bashrc
export HADOOP_HOME=/usr/local/hadoop-.
export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
source ~/.bashrc
           

修改/usr/local/hadoop-2.7.0/etc/hadoop下配置檔案hadoop-env.sh、hdfs-site.xml、core-site.xml、slaves、 mapred-site.xml、yarn-site.xml

  • 檔案 slaves,将作為 DataNode 的主機名寫入該檔案,每行一個。
    【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援
  • 檔案 core-site.xml 改為下面的配置
<configuration> 
<!-- 指定hdfs的nameservice為ns --> 
 <property>          
    <name>fs.defaultFS</name>          
    <value>hdfs://hadoop-ha</value>     
 </property> 
 <!--指定hadoop資料臨時存放目錄--> 
 <property>      
       <name>hadoop.tmp.dir</name>
       <value>file:/usr/local/hadoop-2.7.0/tmp</value>
 </property>
 <property>
       <name>io.file.buffer.size</name>
       <value>4096</value>
 </property> 
 <!--指定zookeeper位址--> 
 <property>      
       <name>ha.zookeeper.quorum</name>
       <value>master:2181,host2:2181,host3:2181</value> 
 </property> 
           
  • 檔案 hdfs-site.xml
<configuration>
    <property>
                <name>dfs.namenode.secondary.http-address</name>
                <value>master:50090</value>
        </property>
        <property>
                <name>dfs.replication</name>
                <value>2</value>
        </property>
        <property>
                <name>dfs.namenode.name.dir</name>
                <value>file:/usr/local/hadoop-2.7.0/tmp/dfs/name</value>
        </property>
        <property>
                <name>dfs.datanode.data.dir</name>
                <value>file:/usr/local/hadoop-2.7.0/tmp/dfs/data</value>
        </property>
       <!--指定hdfs的nameservice為hadoop-ha,需要和core-site.xml中的保持一緻 --> 
    <property>
        <name>dfs.nameservices</name>
        <value>hadoop-ha</value>
    </property>
    <!-- hadoop-ha下面有兩個NameNode,分别是nn1,nn2 -->
    <property>
        <name>dfs.ha.namenodes.hadoop-ha</name>
        <value>nn1,nn2</value>
    </property>
    <!-- nn1的RPC通信位址 -->
        <property>
           <name>dfs.namenode.rpc-address.hadoop-ha.nn1</name>
        <value>master:8020</value>
    </property>
    <!-- nn2的RPC通信位址 -->
    <property>
        <name>dfs.namenode.rpc-address.hadoop-ha.nn2</name>
        <value>host2:8020</value>
    </property>
     <!-- nn1的http通信位址 -->
    <property>
        <name>dfs.namenode.http-address.hadoop-ha.nn1</name>
        <value>master:50070</value>
    </property>
     <!-- nn2的http通信位址 -->
    <property>
        <name>dfs.namenode.http-address.hadoop-ha.nn2</name>
        <value>host2:50070</value>
    </property>
    <!-- 指定NameNode的中繼資料在JournalNode上的存放位置 -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://master:8485;host2:8485;host3:8485/hadoop-ha</value>
    </property>
     <!-- 指定JournalNode在本地磁盤存放資料的位置 -->
    <property>
            <name>dfs.journalnode.edits.dir</name>
            <value>/usr/local/hadoop-2.7.0/journaldata</value>
           </property>
    <property>
        <name>dfs.journalnode.rpc-address</name>
        <value>0.0.0.0:8485</value>
    </property>
    <property>
        <name>dfs.journalnode.http-address</name>
        <value>0.0.0.0:8480</value>
    </property>
           <!-- 開啟NameNode故障時自動切換 -->
    <property>
            <name>dfs.ha.automatic-failover.enabled</name>
            <value>true</value>
    </property> 
    <!-- 配置失敗自動切換實作方式 -->
    <property>
        <name>dfs.client.failover.proxy.provider.hadoop-ha</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>/home/hadoop/.ssh/id_rsa</value>
    </property>
    <!-- 配置sshfence隔離機制逾時時間 -->
    <property>
        <name>dfs.ha.fencing.ssh.connect-timeout</name>
        <value>30000</value>
        </property>
    <property>
        <name>ha.failover-controller.cli-check.rpc-timeout.ms</name>
        <value>60000</value>
    </property> 
    <property>
            <name>ipc.client.connect.timeout</name>
            <value>60000</value>
    </property>
    <property>
            <name>dfs.image.transfer.bandwidthPerSec</name>
            <value>4194304</value>
    </property>
</configuration>
           
  • 檔案 mapred-site.xml
<configuration>
<!-- 指定mr架構為yarn方式 -->  
<property>  
<name>mapreduce.framework.name</name>  
<value>yarn</value>  
</property> 
<property>
<name>mapreduce.jobhistory.address</name>
<value>master:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>master:19888</value>
</property>
<property>
    <name>mapreduce.jobhistory.done-dir</name>
    <value>/history/done</value>
</property>
<property>
    <name>mapreduce.jobhistory.intermediate-done-dir</name>
    <value>/history/done_intermediate</value>
</property>
</configuration>
           
  • 檔案 yarn-site.xml
<configuration>
<!-- 開啟RM高可用 -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 指定RM的cluster id -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>yrc</value>
</property>
<!-- 指定RM的名字 -->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 分别指定RM的位址 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>master</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>host2</value>
</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>
<!-- 指定zk叢集位址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>master:2181,host2:2181,host3:2181</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
           

11.拷貝到其他節點

配置好後,将 master 上的

/usr/local/Hadoop-2.7.0

/usr/local/zookeeper-3.4.6

/usr/lib/jdk1.7.0_51

~/.bashrc

将這四個檔案和目錄拷貝到其他節點上

12.初次配置後啟動順序

12.1 啟動zookeeper叢集

分别在master、host2、host3上執行如下指令啟動zookeeper叢集;

[[email protected]]$zkServer.sh start

驗證叢集zookeeper叢集是否啟動,分别在master、host2、host3上執行如下指令驗證zookeeper叢集是否啟動,叢集啟動成功,有兩個follower節點跟一個leader節點

[[email protected]]$zkServer.sh status

JMX enabled by default

Using config: /usr/local/zookeeper-3.4.6/bin/../conf/zoo.cfg

Mode: follower

12.2 啟動journalnode叢集

在master上執行如下指令完成JournalNode叢集的啟動

[[email protected]]$hadoop-daemons.sh start journalnode

執行jps指令,可以檢視到JournalNode的java程序pid

12.3 格式化zkfc,讓在zookeeper中生成ha節點

在master上執行如下指令,完成格式化

hdfs zkfc –formatZK

(注意,這條指令最好手動輸入,直接copy執行有可能會有問題,當時部署時我是蛋疼了許久)

格式成功後,檢視zookeeper中可以看到

[zk: localhost:2181(CONNECTED) 1] ls /hadoop-ha

[ns]

12.4 格式化hdfs

hadoop namenode –format

(注意,這條指令最好手動輸入,直接copy執行有可能會有問題)

12.5 啟動NameNode

首先在master上啟動active節點,在master上執行如下指令

[[email protected]]$hadoop-daemon.sh start namenode

//在host2上同步namenode的資料,同時啟動standby的namenod,指令如下 把namenode的資料同步到host2上

[[email protected]] hdfsnamenode–bootstrapStandby//啟動host2上的namenode作為standby[hadoop@host2] hadoop-daemon.sh start namenode

12.6 啟動啟動datanode

在mast1上執行如下指令

[[email protected]]$hadoop-daemons.sh start datanode

12.7 啟動yarn

在作為資料總管上的機器上啟動,我這裡是master,執行如下指令完成yarn的啟動

[[email protected]]$ start-yarn.sh

12.8 啟動ZKFC

在master上執行如下指令,完成ZKFC的啟動

[[email protected]] hadoop−daemons.shstartzkfc在host2上執行如下指令,完成ZKFC的啟動[hadoop@host2] hadoop-daemons.sh start zkfc

13.正常啟動順序

//在各個節點上啟動zookeeper

在master啟動hadoop叢集

在master啟動yarn架構

//在備份節點host2上啟動yarn

在master上啟動

mr-jobhistory-daemon.sh start historyserver
           

14.Web通路截圖

【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援
【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援
【Hadoop2.7.0、Zookeeper3.4.6、JDK1.7】搭建完全分布式的hadoop,HA部署安裝,自動備援