1.Hadoop HA簡介及工作原理
Hadoop NameNode官方開始支持HA集群默認(rèn)是從2.0開始狭握,之前的版本均是不支持NameNode HA的高可用的。
1.1 Hadoop HA簡介
Hadoop-HA集群運作機制介紹
- HA即高可用(7*24小時不中斷服務(wù))
- 實現(xiàn)高可用最關(guān)鍵的是消除單點故障
- 分成各個組件的HA機制——HDFS的HA疯溺、YARN的HA
HDFS的HA機制詳解
通過雙namenode消除單點故障论颅,以下為雙namenode協(xié)調(diào)工作的特點:
A、元數(shù)據(jù)管理方式需要改變:
- 內(nèi)存中各自保存一份元數(shù)據(jù)
- Edits日志只能有一份囱嫩,只有Active狀態(tài)的namenode節(jié)點可以做寫操作
- 兩個namenode都可以讀取edits
- 共享的edits放在一個共享存儲中管理(qjournal和NFS兩個主流實現(xiàn))
B恃疯、需要一個狀態(tài)管理功能模塊
- 實現(xiàn)了一個zkfailover,常駐在每一個namenode所在的節(jié)點
- 每一個zkfailover負(fù)責(zé)監(jiān)控自己所在namenode節(jié)點墨闲,利用zk進行狀態(tài)標(biāo)識
- 當(dāng)需要進行狀態(tài)切換時今妄,由zkfailover來負(fù)責(zé)切換
- 切換時需要防止brain split現(xiàn)象的發(fā)生
1.2 Hadoop HA工作原理圖例
HDFS的HA架構(gòu)
使用 Active NameNode,Standby NameNode 兩個結(jié)點解決單點問題,兩個結(jié)點通過JounalNode 共享狀態(tài)盾鳞,采用ZKFC選舉Active實時監(jiān)控集群狀態(tài)犬性,自動進行故障備援。
- Active NameNode:接受 client 的 RPC 請求并處理腾仅,同時寫自己的 Editlog 和共享存儲上的 Editlog仔夺,接收 DataNode 的 Block report, block location updates 和 heartbeat;
- Standby NameNode:同樣會接到來自 DataNode 的 Block report, block location updates 和heartbeat攒砖,同時會從共享存儲的 Editlog 上讀取并執(zhí)行這些 log 操作缸兔,使得自己的 NameNode 中的元數(shù)據(jù)(Namespcae information + Block locations map)都是和 Active NameNode 中的元數(shù)據(jù)是同步的。所以說 Standby 模式的 NameNode 是一個熱備(Hot Standby NameNode)吹艇,一旦切換成 Active 模式惰蜜,馬上就可以提供 NameNode 服務(wù)
- JounalNode:用于Active NameNode , Standby NameNode 同步數(shù)據(jù)受神,本身由一組 JounnalNode 結(jié)點組成抛猖,該組結(jié)點基數(shù)個,支持 Paxos 協(xié)議鼻听,保證高可用财著,是 CDH5 唯一支持的共享方式(相對于 CDH4 促在NFS共享方式)
- ZKFC:監(jiān)控NameNode進程,自動備援撑碴。
YARN的HA架構(gòu)
ResourceManager HA由一對Active撑教,Standby結(jié)點構(gòu)成,通過RMStateStore 存儲內(nèi)部數(shù)據(jù)和主要應(yīng)用的數(shù)據(jù)及標(biāo)記醉拓。
支持可替代的RMStateStore實現(xiàn)方式如下:
- 基于內(nèi)存的MemoryRMStateStore
- 基于文件系統(tǒng)的FileSystemRMStateStore
- 基于 zookeeper的ZKRMStateStore
ResourceManager HA 的架構(gòu)模式同NameNode HA的架構(gòu)模式基本一致伟姐,數(shù)據(jù)共享由 RMStateStore,而ZKFC成為ResourceManager進程的一個服務(wù)亿卤,非獨立存在愤兵。
1.3Hadoop HA解決方案架構(gòu)
Hadoop中的HDFS、MapReduce和YARN的單點故障解決方案架構(gòu)是完全一致的排吴。
- 手動模式:指由管理員通過命令進行主備切換秆乳,這通常在服務(wù)升級時有用。
-
自動模式:自動模式可降低運維成本并自動切換钻哩,但存在潛在危險屹堰,如腦裂。
image
本文將重點介紹下自動模式切換的部署方式憋槐。
什么是腦裂:腦裂是Hadoop2.X版本后出現(xiàn)的全新問題双藕,從字面意思我們可以理解為“大腦分裂”;我們想一下阳仔,當(dāng)一個正常人,突然出現(xiàn)有了兩個大腦,而且這兩個大腦都有自己的意識近范,對于這個人來說肯定是災(zāi)難性問題嘶摊。同理,在Hadoop中评矩,為了防止單點失效問題而出現(xiàn)了兩個namenode(HA機制)叶堆,這兩個namenode正常情況下是起到一個失效,另一個代替的作用斥杜,但在實際運行過程中很有可能出現(xiàn)兩個namenode同時服務(wù)于整個集群的情況虱颗,這種情況稱之為腦裂。
為什么會出現(xiàn)腦裂:腦裂通常發(fā)生在主從namenode切換時蔗喂,由于ActiveNameNode的網(wǎng)絡(luò)延遲忘渔、設(shè)備故障等問題,另一個NameNode會認(rèn)為活躍的NameNode成為失效狀態(tài)缰儿,此時StandbyNameNode會轉(zhuǎn)換成活躍狀態(tài)畦粮,此時集群中將會出現(xiàn)兩個活躍的namenode。因此乖阵,可能出現(xiàn)的因素有網(wǎng)絡(luò)延遲宣赔、心跳故障、設(shè)備故障等瞪浸。
怎么解決腦裂問題:1.新增一條心跳線儒将,防止namennode狀態(tài)無法正常傳達。2.使用隔離機制对蒲,通過調(diào)用活躍節(jié)點中的隔離方法椅棺,讓其主動轉(zhuǎn)換為standby狀態(tài),如果該方法失效則使用遠程調(diào)用執(zhí)行kill -9命令殺死相應(yīng)進程齐蔽,如果該方法仍然無法成功隔離两疚,管理人員可以事先在每臺namenode節(jié)點中編寫一個shell腳本,當(dāng)出現(xiàn)腦裂問題時含滴,執(zhí)行該腳本來切斷電源诱渤,已達到隔離目的。
2.HA環(huán)境準(zhǔn)備
2.1各主機IP規(guī)劃
主機名 | IP地址 | 操作系統(tǒng) | 安裝軟件 | 運行進程 |
---|---|---|---|---|
sre01 | 10.1.8.11 | centos7.6 | jdk谈况、hadoop勺美、zookeeper | NameNode、DFSZKFailoverController(zkfc)碑韵、ResourceManager |
sre02 | 10.1.8.12 | centos7.6 | jdk赡茸、hadoop、zookeeper | NameNode祝闻、DFSZKFailoverController(zkfc)占卧、ResourceManager |
sre03 | 10.1.8.13 | centos7.6 | jdk、hadoop、zookeeper | DataNode华蜒、NodeManager辙纬、JournalNode、QuorumPeerMain |
sre04 | 10.1.8.14 | centos7.6 | jdk叭喜、hadoop贺拣、zookeeper | DataNode、NodeManager捂蕴、JournalNode譬涡、QuorumPeerMain |
sre05 | 10.1.8.15 | centos7.6 | jdk、hadoop啥辨、zookeeper | DataNode涡匀、NodeManager、JournalNode委可、QuorumPeerMain |
注意:針對HA模式渊跋,就不需要SecondaryNameNode了,因為STANDBY狀態(tài)的namenode會負(fù)責(zé)做checkpoint着倾。
2.2添加hosts信息,每臺機器均需執(zhí)行拾酝。
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實現(xiàn)root用戶的免密鑰登錄(正式環(huán)境建議新建用戶)。
- 基本要求如下:
sre01到sre01卡者、sre02蒿囤、sre03、sre04崇决、sre05免秘鑰登錄材诽。
sre02到sre01、sre02恒傻、sre03脸侥、sre04、sre05免秘鑰登錄盈厘。
Ip地址和主機名均可睁枕,本文默認(rèn)使用hostname的方式實現(xiàn)。
- sre01生成密鑰并分發(fā)密鑰至其它機器:
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生成密鑰并分發(fā)密鑰至其它機器:
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并配置環(huán)境變量
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
#聯(lián)系方式:bigdatasafe@gmail.com
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集群部署
根據(jù)規(guī)劃在sre01-05上面分布部署zookeeper節(jié)點沸手。
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分別對應(yīng)1-5外遇,各自執(zhí)行即可。
echo "1" > /home/hadoop/zookeeper-3.4.14/data/myid
3.2配置環(huán)境變量并啟動相關(guān)服務(wù)
配置環(huán)境變量
cat <<EOF > /etc/profile.d/zookeeper.sh
#!/bin/bash
#作者:Adil Lau
#聯(lián)系方式:bigdatasafe@gmail.com
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集群
#聯(lián)系方式:bigdatasafe@gmail.com
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
啟動或關(guān)閉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下載軟件并修改環(huán)境變量
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
#聯(lián)系方式:bigdatasafe@gmail.com
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
#聯(lián)系方式:bigdatasafe@gmail.com
-->
<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
#聯(lián)系方式:bigdatasafe@gmail.com
-->
<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>
<!--發(fā)生failover時契吉,Standby的節(jié)點要執(zhí)行一系列方法把原來那個Active節(jié)點中不健康的NameNode服務(wù)給殺掉跳仿,
這個叫做fence過程。sshfence會通過ssh遠程調(diào)用fuser命令去找到Active節(jié)點的NameNode服務(wù)并殺死它-->
<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
#聯(lián)系方式:bigdatasafe@gmail.com
-->
<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
#聯(lián)系方式:bigdatasafe@gmail.com
-->
<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文件加入節(jié)點信息
cat <<EOF > /home/hadoop/hadoop-2.7.7/etc/hadoop/slaves
sre03
sre04
sre05
EOF
4.7分發(fā)hadoop文件至其他集群節(jié)點
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集群啟動及維護捐晶,需按照順序執(zhí)行菲语。
5.1初始化zookeeper并啟動集群
- 啟動zookeeper節(jié)點:sre03妄辩、sre04、sre05分別執(zhí)行
zkServer.sh start
- 格式化zookeeper節(jié)點:sre01執(zhí)行
hdfs zkfc -formatZK
5.2初始化hadoop并啟動集群
- 啟動journalnode節(jié)點:sre03谨究、sre04恩袱、sre05分別執(zhí)行
hadoop-daemon.sh start journalnode
- 格式化namenode:sre01上執(zhí)行
hdfs namenode -format
- 啟動datanode節(jié)點:sre03泣棋、sre04胶哲、sre05分別執(zhí)行
hdfs namenode -format
- 啟動namenode節(jié)點sre01
hadoop-daemon.sh start namenode
- 啟動namenode節(jié)點sre02
hdfs namenode -bootstrapStandby
hadoop-daemon.sh start namenode
此時sre01和sre02均處于standby狀態(tài)。
- 啟動zkfc服務(wù):sre01潭辈、sre02分別執(zhí)行
hadoop-daemon.sh start zkfc
- 健康狀態(tài)檢查:運行狀態(tài)說明鸯屿。
- 啟動zkfc服務(wù)后,sre01和sre02會自動選舉出active節(jié)點把敢。
- 此時一個節(jié)點為active狀態(tài)寄摆,另一個處于standby狀態(tài)。
5.3 HA故障自動切換測試
集群健康狀態(tài)下修赞,默認(rèn)sre01為active狀態(tài)婶恼,sre02為standby狀態(tài)。
現(xiàn)在模擬sre01節(jié)點故障柏副,將sre01服務(wù)終止測試sre02是否自動切換為active狀態(tài)勾邦。
- sre01節(jié)點執(zhí)行:
jps
16415 DFSZKFailoverController
14213 Jps
15626 NameNode
kill -9 15626
- sre02狀態(tài)查看:
此時sre02由standby狀態(tài)自動切換到active狀態(tài),HA故障自動切換測試成功割择。
注意:生成環(huán)境中由于ResourceManager消耗資源過多眷篇,建議是單獨部署于獨立節(jié)點運行。
至此Hadoop HA集群部署完畢荔泳,如有問題歡迎留言交流蕉饼。微信公眾號:SRE實戰(zhàn),誠邀您的加入玛歌!