您好,登錄后才能下訂單哦!
? 在hadoop1.0的時(shí)候,hdfs集群中namenode存在單點(diǎn)故障的問(wèn)題,當(dāng)namenode不可用的時(shí)候,就會(huì)導(dǎo)致整個(gè)hdfs集群服務(wù)不可用。另外如果需要臨時(shí)對(duì)namenode進(jìn)行設(shè)計(jì)或者其他操作時(shí),停掉namenode之后,hdfs集群也無(wú)法使用了。
? 通過(guò)HA的方式,可以一定程度上解決單點(diǎn)故障問(wèn)題。
1)元數(shù)據(jù)管理方式需要改變:
內(nèi)存中各自保存一份元數(shù)據(jù);
Edits日志只有Active狀態(tài)的namenode節(jié)點(diǎn)可以做寫(xiě)操作;
兩個(gè)namenode都可以讀取edits;
共享的edits放在一個(gè)共享存儲(chǔ)中管理(qjournal和NFS兩個(gè)主流實(shí)現(xiàn));
2)需要一個(gè)狀態(tài)管理功能模塊
hadoop實(shí)現(xiàn)了一個(gè)zkfailover,常駐在每一個(gè)namenode所在的節(jié)點(diǎn),每一個(gè)zkfailover負(fù)責(zé)監(jiān)控自己所在namenode節(jié)點(diǎn),利用zk進(jìn)行狀態(tài)標(biāo)識(shí),當(dāng)需要進(jìn)行狀態(tài)切換時(shí),由zkfailover來(lái)負(fù)責(zé)切換,切換時(shí)需要防止brain split現(xiàn)象的發(fā)生。
3)必須保證兩個(gè)NameNode之間能夠ssh無(wú)密碼登錄。用于后面的隔離。通過(guò)ssh方式到另外的namenode節(jié)點(diǎn)上,將namenode進(jìn)程徹底殺死。防止腦裂。
4)隔離(Fence),即同一時(shí)刻僅僅有一個(gè)NameNode對(duì)外提供服務(wù)
namenode HA自動(dòng)故障轉(zhuǎn)移除了要兩個(gè)namenode之外,還需要增加兩個(gè)組件:zookeeper集群服務(wù),ZKFailoverController(ZKFC)。
它是zookeeper的一個(gè)客戶(hù)端,同時(shí)負(fù)責(zé)監(jiān)控namenode的狀態(tài)。每個(gè)namenode上都運(yùn)行一個(gè)ZKFC進(jìn)程。
1)健康監(jiān)測(cè):
ZKFC使用一個(gè)健康檢查命令定期地ping與之在相同主機(jī)的NameNode,只要該NameNode及時(shí)地回復(fù)健康狀態(tài),ZKFC認(rèn)為該節(jié)點(diǎn)是健康的。如果該節(jié)點(diǎn)崩潰,凍結(jié)或進(jìn)入不健康狀態(tài),健康監(jiān)測(cè)器標(biāo)識(shí)該節(jié)點(diǎn)為非健康的。
2)ZooKeeper會(huì)話(huà)管理:
當(dāng)本地NameNode是健康的,ZKFC保持一個(gè)在ZooKeeper中打開(kāi)的會(huì)話(huà)。如果本地NameNode處于active狀態(tài),ZKFC也保持一個(gè)特殊的znode鎖,該鎖使用了ZooKeeper對(duì)短暫節(jié)點(diǎn)(也就是臨時(shí)節(jié)點(diǎn))的支持,如果會(huì)話(huà)終止,鎖節(jié)點(diǎn)將自動(dòng)刪除。
ZKFC會(huì)在zookeeper上創(chuàng)建一個(gè) /hadoop-ha/namenodeHA集群名稱(chēng)/ 這樣一個(gè)節(jié)點(diǎn),
該節(jié)點(diǎn)上有兩個(gè)子節(jié)點(diǎn):
ActiveBreadCrumb:
持久節(jié)點(diǎn),節(jié)點(diǎn)的值中記錄了 HA集群名稱(chēng) active節(jié)點(diǎn)別名 active節(jié)點(diǎn)地址
主要用于其他想訪問(wèn)namenode服務(wù)的client用于獲取active狀態(tài)的namenode地址,所以必須得是持久節(jié)點(diǎn)。
ActiveStandbyElectorLock:
臨時(shí)節(jié)點(diǎn),節(jié)點(diǎn)的值中記錄了 HA集群名稱(chēng) active節(jié)點(diǎn)別名 active節(jié)點(diǎn)地址。
起到互斥鎖的作用,只有獲取到該節(jié)點(diǎn)的使用權(quán),才能修改上面ActiveBreadCrumb節(jié)點(diǎn)的值。
因?yàn)槭桥R時(shí)節(jié)點(diǎn),所以當(dāng)active namenode和zk保持連接,該節(jié)點(diǎn)就會(huì)一直存在,而standby的namenode也是和zk保持連接,但是發(fā)現(xiàn)該臨時(shí)節(jié)點(diǎn)已存在,就明白已經(jīng)有人占用了,所以它不會(huì)做任何事。當(dāng)上面的active namenode發(fā)生問(wèn)題,不正常了,ZKFC就會(huì)斷開(kāi)和zk的連接,那么臨時(shí)節(jié)點(diǎn)就會(huì)消失。此時(shí)standby namenode就會(huì)重新創(chuàng)建該臨時(shí)節(jié)點(diǎn),相當(dāng)于獲得了鎖,可以修改ActiveBreadCrumb的值。此時(shí)它自己也就順理成章變成新的active namenode。
3)基于ZooKeeper的選擇:
如果本地NameNode是健康的,且ZKFC發(fā)現(xiàn)沒(méi)有其它的節(jié)點(diǎn)當(dāng)前持有znode鎖,它將為自己獲取該鎖。如果成功,則它已經(jīng)贏得了選擇,并負(fù)責(zé)運(yùn)行故障轉(zhuǎn)移進(jìn)程以使它的本地NameNode為active。
主機(jī) | 角色 |
---|---|
bigdata121/192.168.50.121 | namenode,journalnode,datanode,zk |
bigdata122/192.168.50.122 | namenode,journalnode,zk |
bigdata123/192.168.50.123 | zk |
軟件版本 | hadoop2.8.4,zookeeper3.4.10,centos7.2 |
jdk,zookeeper部署不重復(fù)講了,看之前的文章吧
基礎(chǔ)環(huán)境配置:
每個(gè)機(jī)器添加主機(jī)名解析/etc/hosts
每臺(tái)主機(jī)對(duì)自己,以及對(duì)另外兩臺(tái)主機(jī)都要配置ssh免秘鑰登錄
關(guān)閉防火墻以及selinux
hadoop的完整部署可以看之前的文章,這里著重講namenode HA的配置。
修改配置文件:
core-site.xml
<configuration>
<!--指定namenode的HA集群的名字 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!--指定hadoop中hdfs保存數(shù)據(jù)塊和元數(shù)據(jù)塊的目錄-->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/modules/HA/hadoop-2.8.4/data/ha_data</value>
</property>
<!--指定使用的zk集群的所有節(jié)點(diǎn)ip:port-->
<property>
<name>ha.zookeeper.quorum</name>
<value>bigdata121:2181,bigdata122:2181,bigdata123:2181</value>
</property>
</configuration>
hdfs-site.xml
<configuration>
<!-- namenode完全分布式集群名稱(chēng),名字需和core-site中定義的集群名字一樣 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 集群中NameNode節(jié)點(diǎn)都有哪些,這里是節(jié)點(diǎn)的別名 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>bigdata121:9000</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>bigdata122:9000</value>
</property>
<!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>bigdata121:50070</value>
</property>
<!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>bigdata122:50070</value>
</property>
<!-- 指定NameNode元數(shù)據(jù)在JournalNode上的存放位置,用于存放edits日志 ,多個(gè)節(jié)點(diǎn)用逗號(hào)隔開(kāi)-->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://bigdata121:8485;bigdata122:8485/mycluster</value>
</property>
<!-- 配置隔離機(jī)制,即同一時(shí)刻只能有一臺(tái)服務(wù)器對(duì)外響應(yīng),有shell和sshfence兩種方式,主要用于到down掉的namenode所在主機(jī)將進(jìn)程kill掉
防止腦裂的情況 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- 使用隔離機(jī)制時(shí)需要ssh無(wú)秘鑰登錄到另外的主機(jī)上將namenode進(jìn)程kill掉,這里指定私鑰的路徑-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
<!-- 聲明journalnode服務(wù)器存儲(chǔ)目錄-->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/modules/HA/hadoop-2.8.4/data/jn</value>
</property>
<!-- 關(guān)閉權(quán)限檢查-->
<property>
<name>dfs.permissions.enable</name>
<value>false</value>
</property>
<!-- 訪問(wèn)代理類(lèi):client,mycluster,active配置失敗自動(dòng)切換實(shí)現(xiàn)方式。用于訪問(wèn)已配置HA的namenode-->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 啟動(dòng)ha的自動(dòng)故障轉(zhuǎn)移,無(wú)需手動(dòng)切換故障的namenode-->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
配置文件同步到各個(gè)節(jié)點(diǎn)中。使用scp或者rsync隨意吧。
第一次啟動(dòng)時(shí):
cd /opt/modules/HA/hadoop-2.8.4
1)各個(gè)journalnode節(jié)點(diǎn)上啟動(dòng)journalnode服務(wù)
sbin/hadoop-daemon.sh start journalnode
2)nn1上格式化namenode,并啟動(dòng)
bin/hdfs namenode -format
sbin/hadoop-daemon.sh start namenode
3)nn2上通過(guò)啟動(dòng)的journalnode從nn1上同步namenode的數(shù)據(jù)到本地namenode
bin/hdfs namenode -bootstrapStandby
4)啟動(dòng)nn2
sbin/hadoop-daemon.sh start namenode
5)nn1上啟動(dòng)所有datanode
sbin/hadoop-daemons.sh start datanode
6)兩臺(tái)namenode上查看namenode狀態(tài)
bin/hdfs haadmin -getServiceState nn1
bin/hdfs haadmin -getServiceState nn2
正常情況一個(gè)是active,一個(gè)是standby
7)手動(dòng)轉(zhuǎn)換成active和standby
bin/hdfs haadmin -transitionToActive namenode名稱(chēng)
bin/hdfs haadmin -transitionToStandby namenode名稱(chēng)
注意,如果需要手動(dòng)切換,那么需要將hdfs-site.xml中的自動(dòng)切換關(guān)掉。否則報(bào)錯(cuò)。
或者使用 --forceactive 進(jìn)行強(qiáng)制轉(zhuǎn)換。
啟動(dòng)完成后,可以手動(dòng)將active的namenode關(guān)掉,可以看到剛剛standby的namenode會(huì)自動(dòng)轉(zhuǎn)為 active。而剛才關(guān)掉的namenode重新上線的話(huà),就會(huì)變?yōu)閟tandby。
第二次啟動(dòng):
直接start-dfs.sh即可
當(dāng)我們啟動(dòng)完整個(gè)namenode的HA集群之后,我們發(fā)現(xiàn)并沒(méi)有SNN的身影,天真的我以為以為還需要手動(dòng)啟動(dòng),就手動(dòng)啟動(dòng)一發(fā)了,結(jié)果報(bào)錯(cuò)了。
查看SNN的啟動(dòng)日志,可以發(fā)現(xiàn)有這么一個(gè)報(bào)異常信息
org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode: Failed to start secondary namenode
java.io.IOException: Cannot use SecondaryNameNode in an HA cluster. The Standby Namenode will perform checkpointing.
at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.<init>(SecondaryNameNode.java:189)
at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.main(SecondaryNameNode.java:690)
意思很明顯了,就是說(shuō)SNN的職責(zé)由standby的namenode來(lái)完成了,HA狀態(tài)下不需要SNN的存在了。這樣其實(shí)也很合理,可以說(shuō)是充分利用了standby的namenode,免得它閑在那里。
其實(shí)和上面的namenode的ha類(lèi)似,也是借助ZKFC進(jìn)行監(jiān)控RM。
會(huì)在 zk上創(chuàng)建一個(gè) /yarn-leader-election/yarn集群名稱(chēng) 的節(jié)點(diǎn),
下面有兩個(gè)子節(jié)點(diǎn):ActiveBreadCrumb, ActiveStandbyElectorLock
作用類(lèi)似,不重復(fù)講。工作機(jī)制基本類(lèi)似的
主機(jī) | 角色 |
---|---|
bigdata121 | zk, rm |
bigdata122 | zk, rm |
bigdata123 | zk |
yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<!--指定reducer獲取數(shù)據(jù)方式為shuffle機(jī)制-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!--啟動(dòng)日志聚集功能-->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!--指定日志保留時(shí)間為7天,單位是秒-->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
<!--啟用resourcemanager ha-->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!--聲明兩臺(tái)resourcemanager的集群名稱(chēng)-->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster-yarn1</value>
</property>
<!--聲明兩臺(tái)resourcemanager的節(jié)點(diǎn)的別名-->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!--聲明兩臺(tái)rm的地址-->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>bigdata121</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>bigdata122</value>
</property>
<!--指定zookeeper集群的地址-->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>bigdata121:2181,bigdata122:2181,bigdata123:2181</value>
</property>
<!--啟用自動(dòng)恢復(fù),故障自動(dòng)切換-->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!--指定resourcemanager的狀態(tài)信息存儲(chǔ)在zookeeper集群-->
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
</configuration>
配置文件同步到其他節(jié)點(diǎn)。
bigdata121:?jiǎn)?dòng)yarn
sbin/start-yarn.sh
bigdata122:?jiǎn)?dòng)rm
sbin/yarn-daemon.sh start resourcemanager
查看服務(wù)狀態(tài):
bin/yarn rmadmin -getServiceState rm1
bin/yarn rmadmin -getServiceState rm2
測(cè)試方式和namenode類(lèi)似,這里不重復(fù)
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。