使用 QJM 實(shí)現(xiàn) HDFS 的 HA
本文是在hadoop集群部署(yarn)基礎(chǔ)上增加的配置內(nèi)容,因?yàn)槟瞧鄙貶DFS的HA配置,在生產(chǎn)環(huán)境不夠完整。
hadoop官方提供了兩種HDFS的HA配置方案,兩種方案殊途同歸,但是需要的錢(qián)、精力和技術(shù)不同。
如果對(duì)HDFS架構(gòu)熟悉的話(huà)(如果不熟悉,可以通過(guò)HDFS架構(gòu)了解),就應(yīng)該知道,NameNode通過(guò)FsImage和EditLog兩個(gè)文件管理DataNode的數(shù)據(jù),Secondary NameNode會(huì)定期合并EditLog,以減少NameNode啟動(dòng)時(shí)的安全檢查。EditLog文件存儲(chǔ)的是對(duì)文件的一條條的操作,也就是說(shuō),只要保證有另外一個(gè)NameNode的EditLog文件一直與當(dāng)前正在運(yùn)行的NameNode的EditLog文件是一樣的,那就可以隨時(shí)使用新的NameNode替換老的NameNode。官方目前給出的兩種HA方案也大體是這樣:
QJM:the Quorum Journal Manager,翻譯是法定經(jīng)濟(jì)管理人,實(shí)在沒(méi)法想象,所以大家都親切的稱(chēng)之為QJM。這種方案是通過(guò)JournalNode共享EditLog的數(shù)據(jù),使用的是Paxos算法(沒(méi)錯(cuò),zookeeper就是使用的這種算法),保證活躍的NameNode與備份的NameNode之間EditLog日志一致。
NFS:Network File System 或 Conventional Shared Storage,傳統(tǒng)共享存儲(chǔ),其實(shí)就是在服務(wù)器掛載一個(gè)網(wǎng)絡(luò)存儲(chǔ)(比如NAS),活躍NameNode將EditLog的變化寫(xiě)到NFS,備份NameNode檢查到修改就讀取過(guò)來(lái),是兩個(gè)NameNode數(shù)據(jù)一致。
客觀的說(shuō),Secondary NameNode也算是對(duì)NameNode的備份,但是使用Secondary NameNode需要手動(dòng)處理,不如QJM和NFS兩種可以自動(dòng)處理簡(jiǎn)單,所以沒(méi)有被列入HA解決方案中。
但是,這兩種方案在部署方式上差別比較大。QJM需要啟動(dòng)幾個(gè)JournalNode即可,NFS需要掛在一個(gè)共享存儲(chǔ)。因?yàn)闂l件限制,我只能通過(guò)QJM的方式實(shí)現(xiàn)HDFS的HA,如果想看NFS方案,可以直接看官方文檔。
1. hdfs-site.xml
dfs.nameservices:指定nameservice的名稱(chēng),這個(gè)需要自定義,可以是任意的名稱(chēng)。這個(gè)值需要用在后面的配置和HDFS集群管理路徑中。
<property> <name>dfs.nameservices</name> <value>mycluster</value> </property>
dfs.ha.namenodes.[nameservice ID]:指定集群中兩個(gè)NameNode的id,目前只能支持最多兩個(gè)NameNode,所以就需要兩個(gè)id,以逗號(hào)分隔。
<property> <name>dfs.ha.namenodes.mycluster</name> <value>nn1,nn2</value> </property>
dfs.namenode.rpc-address.[nameservice ID].[namenode ID]:指定NameNode的rpc地址,用于數(shù)據(jù)傳輸。因?yàn)橛袃蓚€(gè)NameNode,所以需要給出兩個(gè)節(jié)點(diǎn)。
<property> <name>dfs.namenode.rpc-address.mycluster.nn1</name> <value>s108:8020</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn2</name> <value>s109:8020</value> </property>
dfs.name.http-address.[nameservice ID].[namenode ID]:同3,還需要http地址。
<property> <name>dfs.namenode.http-address.mycluster.nn1</name> <value>s108:50070</value> </property> <property> <name>dfs.namenode.http-address.mycluster.nn2</name> <value>s109:50070</value> </property>
dfs.namenode.shared.edits.dir:需要提供JournalNode的配置地址,用于活躍NameNode向該位置寫(xiě)變化數(shù)據(jù),備份NameNode從該位置讀取數(shù)據(jù)應(yīng)用與自身。如果配置過(guò)Kafka就應(yīng)該可以理解這個(gè)。配置地址格式是:qjournal://host1:port1;hots2:port2;host3:port3/journalId,地址端口為一對(duì),每對(duì)之間通過(guò)分號(hào)隔開(kāi),最后的journalId是為了區(qū)分不同的nameservice的。也就是說(shuō),一組JournalNode可以支撐多個(gè)NameNode的HA配置。所以,比較好的配置方式是,journalId與nameservice的名稱(chēng)一致。
<property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://s108:8485;s109:8485;s110:8485/mycluster</value> </property>
dfs.client.failover.proxy.provider.[nameservice ID]:HDFS客戶(hù)端連接活躍NameNode的方式,配置一個(gè)Java類(lèi)。因?yàn)镹ameNode只有一個(gè)是活躍的,也就是只有一個(gè)提供服務(wù),另一個(gè)是備份。所以客戶(hù)端需要知道哪個(gè)是活躍節(jié)點(diǎn)。所以需要某種方式找到這個(gè)活躍節(jié)點(diǎn)。這里提供一個(gè)代理類(lèi),目前Hadoop只實(shí)現(xiàn)了一個(gè)代理類(lèi)ConfiguredFailoverProxyProvider,也可以自己定義:
<property> <name>dfs.client.failover.proxy.provider.mycluster</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property>
dfs.ha.fencing.methods:用于故障轉(zhuǎn)移過(guò)程中,在活躍節(jié)點(diǎn)執(zhí)行的一組腳本或Java類(lèi)。HDFS集群有一條原則是:只能有一個(gè)NameNode處于活躍狀態(tài)。QJM只允許一個(gè)NameNode寫(xiě)入JournalNode集群,所以可以避免鬧裂的發(fā)生。但是故障轉(zhuǎn)移過(guò)程中,還可能會(huì)有其他的問(wèn)題,所以需要提供一些防護(hù)方法。需要注意的是,如果不想使用具體的防護(hù)方法,也必須提供一個(gè)腳本,比如shell(/bin/true)。
sshfence:通過(guò)ssh方式連接活躍NameNode,并kill掉進(jìn)程。所以還需要通過(guò)dfs.ha.fencing.ssh.private-key-files配置ssh key,還可以通過(guò)dfs.ha.fencing.ssh.connect-timeout配置ssh連接超時(shí)時(shí)間。
<property> <name>dfs.ha.fencing.methods</name> <value>sshfence</value> </property> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property> <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>30000</value> </property>
如果對(duì)于不是標(biāo)準(zhǔn)ssh端口或相同用戶(hù)的,可以在sshfence后添加用戶(hù)名和端口,格式為sshfence([[username][:port]])。
shell:運(yùn)行任意的腳本來(lái)進(jìn)行防護(hù)。我是使用sshfence方式配置的,所以下面就列出配置格式,具體信息查看官網(wǎng)。
<property> <name>dfs.ha.fencing.methods</name> <value>shell(/path/to/my/script.sh arg1 arg2 ...)</value> </property>
dfs.journalnode.edits.dir:JournalNode守護(hù)進(jìn)程存儲(chǔ)數(shù)據(jù)的本地路徑。這是啟動(dòng)JournalNode需要配置的配置項(xiàng)。當(dāng)然整個(gè)集群配置相同也不會(huì)有不好的影響,需要是本地絕對(duì)路徑。
<property> <name>dfs.journalnode.edits.dir</name> <value>/data/hadoop/journal</value> </property>
dfs.ha.automatic-failover.enabled:自動(dòng)故障轉(zhuǎn)移,該配置向需要與core-site.xml中的ha.zookeeper.quorum配合使用。
<property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property>
2. core-site.xml
fs.defaultFS:這個(gè)在單點(diǎn)NameNode的時(shí)候配置過(guò),這里需要再次配置,需要使用hdfs-site.xml中的nameservice名稱(chēng)。
<property> <name>fs.defaultFS</name> <value>hdfs://mycluster</value> </property>
ha.zookeeper.quorum:這個(gè)就是前面提到hdfs-site.xml中配置自動(dòng)故障轉(zhuǎn)移配合使用的配置項(xiàng),需要提供zookeeper集群地址
<property> <name>ha.zookeeper.quorum</name> <value>s109:2181,s110:2181,s111:2181</value> </property>
3. 開(kāi)始啟動(dòng)
3.1 JournalNode
需要首先啟動(dòng)JournalNode,如上面配置的,需要s108/s109/s110三個(gè)節(jié)點(diǎn)啟動(dòng)JournalNode,默認(rèn)端口就是8045。啟動(dòng)命令是hadoop-daemon.sh start journalnode。
3.2 NameNode數(shù)據(jù)準(zhǔn)備
JournalNode啟動(dòng)完成后,因?yàn)橛袃蓚€(gè)NameNode節(jié)點(diǎn),就需要先同步兩個(gè)NameNode節(jié)點(diǎn)的數(shù)據(jù)。
如果是全新的HDFS集群,這個(gè)時(shí)候直接hdfs namenode -format格式化即可
已經(jīng)格式化或是從非HA設(shè)置為HA的集群,需要把格式化后的NameNode節(jié)點(diǎn)的數(shù)據(jù)拷貝到為格式化節(jié)點(diǎn)上。未格式化NameNode節(jié)點(diǎn)執(zhí)行hdfs namenode -bootstrapStandby命令。
如果是從非HA到HA的配置,需要執(zhí)行hdfs namenode -initializeSharedEdits將原有的NameNode日志寫(xiě)入JournalNode中。
3.3 Zookeeper中的HA狀態(tài)
因?yàn)樯厦媾渲昧俗詣?dòng)故障轉(zhuǎn)移,所以需要在Zookeeper中初始化HA狀態(tài)。執(zhí)行命令hdfs zkfc -formatZK。
3.4 啟動(dòng)
直接使用start-dfs.sh命令啟動(dòng)NameNode、DataNode,以及ZKFS進(jìn)程,啟動(dòng)成功之后就可以通過(guò)s108:50070和s109:50070訪(fǎng)問(wèn)web頁(yè)面查看具體哪個(gè)NameNode是Active或Standby狀態(tài)的了。
啟動(dòng)的時(shí)候可以注意到,啟動(dòng)過(guò)程沒(méi)有啟動(dòng)Secondary NameNode,這是用為HA不會(huì)啟動(dòng)Secondary NameNode。也就是master配置文件配置內(nèi)容無(wú)效了。
4. 管理
可以通過(guò)hdfs haadmin命令進(jìn)行管理。具體查看官網(wǎng)說(shuō)明。
參考
1. HDFS High Availability Using the Quorum Journal Manager
2. HDFS High Availability
