天天看點

hadoop-2.7.7 HA完全分布式叢集部署詳解

1.Hadoop HA簡介及工作原理

Hadoop NameNode官方開始支援HA叢集預設是從2.0開始,之前的版本均是不支援NameNode HA的高可用的。

1.1 Hadoop HA簡介

Hadoop-HA叢集運作機制介紹
  • HA即高可用(7*24小時不中斷服務)
  • 實作高可用最關鍵的是消除單點故障
  • 分成各個元件的HA機制——HDFS的HA、YARN的HA
HDFS的HA機制詳解

通過雙namenode消除單點故障,以下為雙namenode協調工作的特點:

A、中繼資料管理方式需要改變:

  • 記憶體中各自儲存一份中繼資料
  • Edits日志隻能有一份,隻有Active狀态的namenode節點可以做寫操作
  • 兩個namenode都可以讀取edits
  • 共享的edits放在一個共享存儲中管理(qjournal和NFS兩個主流實作)

B、需要一個狀态管理功能子產品

  • 實作了一個zkfailover,常駐在每一個namenode所在的節點
  • 每一個zkfailover負責監控自己所在namenode節點,利用zk進行狀态辨別
  • 當需要進行狀态切換時,由zkfailover來負責切換
  • 切換時需要防止brain split現象的發生

1.2 Hadoop HA工作原理圖例

HDFS的HA架構

使用 Active NameNode,Standby NameNode 兩個結點解決單點問題,兩個結點通過JounalNode 共享狀态,采用ZKFC選舉Active實時監控叢集狀态,自動進行故障備援。

  • Active NameNode:接受 client 的 RPC 請求并處理,同時寫自己的 Editlog 和共享存儲上的 Editlog,接收 DataNode 的 Block report, block location updates 和 heartbeat;
  • Standby NameNode:同樣會接到來自 DataNode 的 Block report, block location updates 和heartbeat,同時會從共享存儲的 Editlog 上讀取并執行這些 log 操作,使得自己的 NameNode 中的中繼資料(Namespcae information + Block locations map)都是和 Active NameNode 中的中繼資料是同步的。是以說 Standby 模式的 NameNode 是一個熱備(Hot Standby NameNode),一旦切換成 Active 模式,馬上就可以提供 NameNode 服務
  • JounalNode:用于Active NameNode , Standby NameNode 同步資料,本身由一組 JounnalNode 結點組成,該組結點基數個,支援 Paxos 協定,保證高可用,是 CDH5 唯一支援的共享方式(相對于 CDH4 促在NFS共享方式)
  • ZKFC:監控NameNode程序,自動備援。
YARN的HA架構

ResourceManager HA由一對Active,Standby結點構成,通過RMStateStore 存儲内部資料和主要應用的資料及标記。

支援可替代的RMStateStore實作方式如下:

  • 基于記憶體的MemoryRMStateStore
  • 基于檔案系統的FileSystemRMStateStore
  • 基于 zookeeper的ZKRMStateStore

    ResourceManager HA 的架構模式同NameNode HA的架構模式基本一緻,資料共享由 RMStateStore,而ZKFC成為ResourceManager程序的一個服務,非獨立存在。

1.3Hadoop HA解決方案架構

Hadoop中的HDFS、MapReduce和YARN的單點故障解決方案架構是完全一緻的。

  • 手動模式:指由管理者通過指令進行主備切換,這通常在服務更新時有用。
  • 自動模式:自動模式可降低運維成本并自動切換,但存在潛在危險,如腦裂。

本文将重點介紹下自動模式切換的部署方式。

什麼是腦裂:腦裂是Hadoop2.X版本後出現的全新問題,從字面意思我們可以了解為“大腦分裂”;我們想一下,當一個正常人,突然出現有了兩個大腦,而且這兩個大腦都有自己的意識,對于這個人來說肯定是災難性問題。同理,在Hadoop中,為了防止單點失效問題而出現了兩個namenode(HA機制),這兩個namenode正常情況下是起到一個失效,另一個代替的作用,但在實際運作過程中很有可能出現兩個namenode同時服務于整個叢集的情況,這種情況稱之為腦裂。

為什麼會出現腦裂:腦裂通常發生在主從namenode切換時,由于ActiveNameNode的網絡延遲、裝置故障等問題,另一個NameNode會認為活躍的NameNode成為失效狀态,此時StandbyNameNode會轉換成活躍狀态,此時叢集中将會出現兩個活躍的namenode。是以,可能出現的因素有網絡延遲、心跳故障、裝置故障等。

怎麼解決腦裂問題:1.新增一條心跳線,防止namennode狀态無法正常傳達。2.使用隔離機制,通過調用活躍節點中的隔離方法,讓其主動轉換為standby狀态,如果該方法失效則使用遠端調用執行kill -9指令殺死相應程序,如果該方法仍然無法成功隔離,管理人員可以事先在每台namenode節點中編寫一個shell腳本,當出現腦裂問題時,執行該腳本來切斷電源,已達到隔離目的。

2.HA環境準備

2.1各主機IP規劃

主機名 IP位址 作業系統 安裝軟體 運作程序
sre01 10.1.8.11 centos7.6 jdk、hadoop、zookeeper NameNode、DFSZKFailoverController(zkfc)、ResourceManager
sre02 10.1.8.12
sre03 10.1.8.13 DataNode、NodeManager、JournalNode、QuorumPeerMain
sre04 10.1.8.14
sre05 10.1.8.15
注意:針對HA模式,就不需要SecondaryNameNode了,因為STANDBY狀态的namenode會負責做checkpoint。

2.2添加hosts資訊,每台機器均需執行。

cat <<EOF > /etc/hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.1.8.11 sre01
10.1.8.12 sre02
10.1.8.13 sre03
10.1.8.14 sre04
10.1.8.15 sre05
EOF           

2.3實作root使用者的免密鑰登入(正式環境建議建立使用者)。

  • 基本要求如下:
sre01到sre01、sre02、sre03、sre04、sre05免秘鑰登入。
sre02到sre01、sre02、sre03、sre04、sre05免秘鑰登入。
Ip位址和主機名均可,本文預設使用hostname的方式實作。           
  • sre01生成密鑰并分發密鑰至其它機器:
ssh-keygen -t rsa  # 一路回車
ssh-copy-id -i ~/.ssh/id_rsa.pub sre01
ssh-copy-id -i ~/.ssh/id_rsa.pub sre02
ssh-copy-id -i ~/.ssh/id_rsa.pub sre03
ssh-copy-id -i ~/.ssh/id_rsa.pub sre04
ssh-copy-id -i ~/.ssh/id_rsa.pub sre05           
  • sre02生成密鑰并分發密鑰至其它機器:
ssh-keygen -t rsa  # 一路回車
ssh-copy-id -i ~/.ssh/id_rsa.pub sre01
ssh-copy-id -i ~/.ssh/id_rsa.pub sre02
ssh-copy-id -i ~/.ssh/id_rsa.pub sre03
ssh-copy-id -i ~/.ssh/id_rsa.pub sre04
ssh-copy-id -i ~/.ssh/id_rsa.pub sre05           

2.4安裝JDK并配置環境變量

mkdir -p /usr/java/ /root/software && cd software
wget https://file.bigdatasafe.org/software/jdk/jdk-8u211-linux-x64.tar.gz
tar zxvf jdk-8u211-linux-x64.tar.gz -C /usr/java/
cat <<EOF > /etc/profile.d/jdk.sh
#!/bin/bash
#作者:Adil Lau
#聯系方式:[email protected]
export JAVA_HOME=/usr/java/jdk1.8.0_211
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$PATH
EOF
chmod a+x /etc/profile.d/jdk.sh
source /etc/profile.d/jdk.sh           

3.zookeeper叢集部署

根據規劃在sre01-05上面分布部署zookeeper節點。

3.1下載下傳zookeeper并修改配置檔案

mkdir -p /home/hadoop/ /root/software && cd software
wget https://file.bigdatasafe.org/software/zookeeper/zookeeper-3.4.14.tar.gz
tar zxvf zookeeper-3.4.14.tar.gz -C /home/hadoop/
mkdir -p /home/hadoop/zookeeper-3.4.14/{logs,data}
cat <<EOF > /home/hadoop/zookeeper-3.4.14/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/hadoop/zookeeper-3.4.14/data
dataLogDir=/home/hadoop/zookeeper-3.4.14/logs
clientPort=2181
autopurge.snapRetainCount=500
autopurge.purgeInterval=24
server.1=sre01:2888:3888
server.2=sre02:2888:3888
server.3=sre03:2888:3888
server.4=sre04:2888:3888
server.5=sre05:2888:3888
EOF
#sre01-05分别對應1-5,各自執行即可。
echo "1" > /home/hadoop/zookeeper-3.4.14/data/myid           

3.2配置環境變量并啟動相關服務

配置環境變量
cat <<EOF > /etc/profile.d/zookeeper.sh
#!/bin/bash
#作者:Adil Lau
#聯系方式:[email protected]
export ZOOKEEPER_HOME=/home/hadoop/zookeeper-3.4.14/
export PATH=$ZOOKEEPER_HOME/bin:$PATH
EOF
chmod a+x /etc/profile.d/zookeeper.sh
source /etc/profile.d/zookeeper.sh           
制作啟動腳本
cat <<EOF > /home/hadoop/zookeeper-3.4.14/bin/zk.sh
#!/bin/bash
#作者:Adil Lau
#部落格:www.bigdatasafe.org
#目的:一鍵啟動zookeeper叢集
#聯系方式:[email protected]
iparray=(sre01 sre02 sre03 sre04 sre05)  
user="root"  
echo "$1"  
if [ $1 = "start" ]  
then  
        cmd="zkServer.sh start"  
fi  
  
if [ $1 = "stop" ]  
then  
        cmd="zkServer.sh stop"  
fi  
  
cmd2="jps"  
  
for ip in ${iparray[*]}  
do  
        echo "ssh to $ip"  
        ssh -t $user@$ip "$cmd"  
        echo "jps:"  
        ssh -t $user@$ip "$cmd2"  
        echo  
done
EOF
chmod a+x /home/hadoop/zookeeper-3.4.14/bin/zk.sh           
啟動或關閉zookeeper叢集
#啟動方式
/home/hadoop/zookeeper-3.4.14/bin/zk.sh start
#停止方式
/home/hadoop/zookeeper-3.4.14/bin/zk.sh stop           

4.Hadoop HA叢集部署

4.1下載下傳軟體并修改環境變量

wget https://file.bigdatasafe.org/software/hadoop/hadoop-2.7.7.tar.gz
tar zxvf hadoop-2.7.7.tar.gz -C /home/hadoop/
mkdir -p /home/hadoop/hadoop-2.7.7/{logs,tmp,name,data,journal}
cat <<EOF > /etc/profile.d/hadoop.sh
#!/bin/bash
#作者:Adil Lau
#聯系方式:[email protected]
export HADOOP_HOME=/home/hadoop/hadoop-2.7.7
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
EOF
chmod a+x /etc/profile.d/hadoop.sh
source /etc/profile.d/hadoop.sh           

4.2修改core-site.xml配置檔案

cat <<EOF > /home/hadoop/hadoop-2.7.7/etc/hadoop/core-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
#作者:Adil Lau
#聯系方式:[email protected]
-->
<configuration>
 <property>
     <name>fs.defaultFS</name>
     <value>hdfs://hadoopha</value>
 </property>
 <property>
     <name>hadoop.tmp.dir</name>
     <value>file:/home/hadoop/hadoop-2.7.7/tmp</value>
 </property>
 <property>
    <name>ha.zookeeper.quorum</name>
    <value>sre01:2181,sre02:2181,sre03:2181,sre04:2181,sre05:2181</value>
 </property>
 <property>
    <name>ha.zookeeper.session-timeout.ms</name>
    <value>15000</value>
 </property>
</configuration>
EOF           

4.3修改hdfs-site.xml配置檔案

cat <<EOF > /home/hadoop/hadoop-2.7.7/etc/hadoop/hdfs-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
#作者:Adil Lau
#聯系方式:[email protected]
-->
<configuration>
 <property>
     <name>dfs.namenode.name.dir</name>
     <value>file:/home/hadoop/hadoop-2.7.7/name</value>
 </property>
 <property>
     <name>dfs.datanode.data.dir</name>
     <value>file:/home/hadoop/hadoop-2.7.7/data</value>
 </property>
 <property>
     <name>dfs.replication</name>
     <value>3</value>
 </property>
 <!--HA配置 -->
 <property>
     <name>dfs.nameservices</name>
     <value>hadoopha</value>
 </property>
 <property>
     <name>dfs.ha.namenodes.hadoopha</name>
     <value>nn1,nn2</value>
 </property>
 <!--namenode1 RPC端口 -->
 <property>
     <name>dfs.namenode.rpc-address.hadoopha.nn1</name>
     <value>sre01:9000</value>
 </property>
 <!--namenode1 HTTP端口 -->
 <property>
     <name>dfs.namenode.http-address.hadoopha.nn1</name>
     <value>sre01:50070</value>
 </property>
 <!--namenode2 RPC端口 -->
 <property>
     <name>dfs.namenode.rpc-address.hadoopha.nn2</name>
     <value>sre02:9000</value>
 </property>
  <!--namenode2 HTTP端口 -->
 <property>
     <name>dfs.namenode.http-address.hadoopha.nn2</name>
     <value>sre02:50070</value>
 </property>
  <!--HA故障切換 -->
 <property>
     <name>dfs.ha.automatic-failover.enabled</name>
     <value>true</value>
 </property>
 <!-- journalnode 配置 -->
 <property>
     <name>dfs.namenode.shared.edits.dir</name>
     <value>qjournal://sre03:8485;sre04:8485;sre05:8485/hadoopha</value>
 </property>
 <property>
     <name>dfs.client.failover.proxy.provider.hadoopha</name>
     <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
 </property>
 <!--發生failover時,Standby的節點要執行一系列方法把原來那個Active節點中不健康的NameNode服務給殺掉,
 這個叫做fence過程。sshfence會通過ssh遠端調用fuser指令去找到Active節點的NameNode服務并殺死它-->
 <property>
     <name>dfs.ha.fencing.methods</name>
     <value>shell(/bin/true)</value>
  </property>
   <!--SSH私鑰 -->
  <property>
      <name>dfs.ha.fencing.ssh.private-key-files</name>
      <value>/root/.ssh/id_rsa</value>
  </property>
 <!--SSH逾時時間 -->
  <property>
      <name>dfs.ha.fencing.ssh.connect-timeout</name>
      <value>30000</value>
  </property>
  <!--Journal Node檔案存儲位址 -->
  <property>
      <name>dfs.journalnode.edits.dir</name>
      <value>/home/hadoop/hadoop-2.7.7/journal</value>
  </property>
</configuration>
EOF           

4.4修改yarn-site.xml配置檔案

cat <<EOF > /home/hadoop/hadoop-2.7.7/etc/hadoop/yarn-site.xml
<?xml version="1.0"?>
<!--
#作者:Adil Lau
#聯系方式:[email protected]
-->
<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>sre01</value>
    </property>
    <property>
         <name>yarn.resourcemanager.hostname.rm2</name>
         <value>sre02</value>
    </property>
    <!-- 指定zk叢集位址 -->
    <property>
         <name>yarn.resourcemanager.zk-address</name>
         <value>sre01:2181,sre02:2181,sre03:2181,sre04:2181,sre05:2181</value>
    </property>
    <property>
         <name>yarn.nodemanager.aux-services</name>
         <value>mapreduce_shuffle</value>
    </property>
</configuration>
EOF           

4.5修改mapred-site.xml配置檔案

cat <<EOF > /home/hadoop/hadoop-2.7.7/etc/hadoop/mapred-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
#作者:Adil Lau
#聯系方式:[email protected]
-->
<configuration>
   <property>
          <name>mapreduce.framework.name</name>
          <value>yarn</value>
   </property>
   <property>
         <name>mapreduce.map.memory.mb</name>
         <value>2048</value>
   </property>
   <property>
          <name>mapreduce.reduce.memory.mb</name>
          <value>2048</value>
   </property>
</configuration>
EOF           

4.6修改slaves檔案加入節點資訊

cat <<EOF > /home/hadoop/hadoop-2.7.7/etc/hadoop/slaves
sre03
sre04
sre05
EOF           

4.7分發hadoop檔案至其他叢集節點

scp -r /home/hadoop/hadoop-2.7.7 sre02:/home/hadoop
scp -r /home/hadoop/hadoop-2.7.7 sre03:/home/hadoop
scp -r /home/hadoop/hadoop-2.7.7 sre04:/home/hadoop
scp -r /home/hadoop/hadoop-2.7.7 sre05:/home/hadoop           

5.Hadoop HA叢集啟動及維護,需按照順序執行。

5.1初始化zookeeper并啟動叢集

  • 啟動zookeeper節點:sre03、sre04、sre05分别執行
zkServer.sh start           
  • 格式化zookeeper節點:sre01執行
hdfs zkfc -formatZK           

5.2初始化hadoop并啟動叢集

  • 啟動journalnode節點:sre03、sre04、sre05分别執行
hadoop-daemon.sh  start journalnode           
  • 格式化namenode:sre01上執行
hdfs namenode -format           
  • 啟動datanode節點:sre03、sre04、sre05分别執行
hdfs namenode -format           
  • 啟動namenode節點sre01
hadoop-daemon.sh start namenode           
  • 啟動namenode節點sre02
hdfs namenode -bootstrapStandby
hadoop-daemon.sh start namenode           
此時sre01和sre02均處于standby狀态。
  • 啟動zkfc服務:sre01、sre02分别執行
hadoop-daemon.sh  start zkfc           
  • 健康狀态檢查:運作狀态說明。
    • 啟動zkfc服務後,sre01和sre02會自動選舉出active節點。
    • 此時一個節點為active狀态,另一個處于standby狀态。

5.3 HA故障自動切換測試

**叢集健康狀态下,預設sre01為active狀态,sre02為standby狀态。

現在模拟sre01節點故障,将sre01服務終止測試sre02是否自動切換為active狀态。**

  • sre01節點執行:
jps
16415 DFSZKFailoverController
14213 Jps
15626 NameNode
kill -9 15626           
  • sre02狀态檢視:

此時sre02由standby狀态自動切換到active狀态,HA故障自動切換測試成功。

注意:生成環境中由于ResourceManager消耗資源過多,建議是單獨部署于獨立節點運作。

至此Hadoop HA叢集部署完畢,如有問題歡迎留言交流。