HDFS-Hadoop NameNode高可用機(jī)制
1 - 為什么要高可用
在 Hadoop 中,NameNode 扮演著至關(guān)重要的角色 —— 整個(gè) HDFS 文件系統(tǒng)的元數(shù)據(jù)信息都由 NameNode 管理,一旦 NameNode 進(jìn)程出現(xiàn)異常,或者維護(hù) NameNode 所在節(jié)點(diǎn)的時(shí)候,都會(huì)導(dǎo)致 HDFS 集群不可用。
所以 NameNode 的可用性直接決定了 Hadoop 集群的可用性。
2 - NameNode 的高可用發(fā)展史
在 Hadoop 2.0 以前,每個(gè) HDFS 集群只有一個(gè) NameNode,一旦這個(gè)節(jié)點(diǎn)不可用,則整個(gè) HDFS 集群將處于不可用狀態(tài) —— 即,HDFS 2.0 以前,NameNode 存在單點(diǎn)故障風(fēng)險(xiǎn)。
與典型的 HA(High Availability,高可用)方案一樣(參考:常見(jiàn)的六種容錯(cuò)機(jī)制),HDFS 2.0 開(kāi)始支持的 HA,就是 在 HDFS 集群中同時(shí)運(yùn)行兩個(gè) NameNode。
一個(gè)處于 Active(活躍)狀態(tài):負(fù)責(zé)集群中所有客戶端的操作(修改命名空間、刪除備份數(shù)據(jù)塊等操作);
另一個(gè)處于 Standby(備份)狀態(tài):充當(dāng)從服務(wù)器,和 Active NameNode 有相同的命名空間和元數(shù)據(jù)。
當(dāng) Active NameNode 停止服務(wù)時(shí),Standby NameNode 能夠快速進(jìn)行故障切換,以保證 HDFS 集群服務(wù)不受影響。
3 - HDFS 的高可用架構(gòu)
看圖:
Standby NemeNode 是如何做到故障切換的?換句話說(shuō),它和 Active NameNode 之間的數(shù)據(jù)是如何保持一致的?
3.1 Standby 和 Active 的命名空間保持一致
它們存儲(chǔ)著一樣的元數(shù)據(jù),可以把集群恢復(fù)到系統(tǒng)奔潰時(shí)的狀態(tài) —— 這是實(shí)現(xiàn)自動(dòng)故障切換的基礎(chǔ)。
為了使備份節(jié)點(diǎn)與活動(dòng)節(jié)點(diǎn)的數(shù)據(jù)保持同步,兩個(gè)節(jié)點(diǎn)都需要同一組獨(dú)立運(yùn)行的節(jié)點(diǎn)來(lái)通信,HDFS 中把這樣的節(jié)點(diǎn)稱為 JournalNode。
1)第一關(guān)系鏈的一致性,即 Active NameNode 和 Standby NameNode 的命名空間狀態(tài)的一致性:
a)Active NameNode 會(huì)定期地把 修改命名空間或刪除備份數(shù)據(jù)塊等操作 記錄到 EditLog,同時(shí)寫(xiě)到 JN 的多數(shù)節(jié)點(diǎn)中。
b)Standby NameNode 會(huì)一直監(jiān)聽(tīng) JN 上 EditLog的變化,如果 editlog 有改動(dòng),Standby NameNode 就會(huì)讀取 editlog 并與當(dāng)前的命名空間合并。
c)Active NameNode 出現(xiàn)故障時(shí),Standby NameNode 會(huì)保證已經(jīng)從 JN 上讀取了所有 editlog 并與命名空間合并,然后才會(huì)從 Standby 切換為 Active。
2)第二關(guān)系鏈的一致性,即數(shù)據(jù)塊的存儲(chǔ)信息的一致性:
為了使故障切換能夠盡快執(zhí)行成功,就要保證 Standby NameNode 也 實(shí)時(shí)保存了數(shù)據(jù)塊的存儲(chǔ)信息,HDFS 中是這樣做的:
DataNode 會(huì)同時(shí)向兩個(gè) NameNode 發(fā)送心跳以及塊的存儲(chǔ)信息。
這樣以來(lái),發(fā)生故障切換時(shí),Standby NameNode 就可以直接切換到 Active 狀態(tài)(它和舊 Active 節(jié)點(diǎn)的元數(shù)據(jù)完全一致),而不需要等待所有的 DataNode 匯報(bào)全量數(shù)據(jù)塊信息 —— 這也是熱備功能。
需要注意:Standby NameNode 只會(huì)更新數(shù)據(jù)塊的存儲(chǔ)信息,并不會(huì)向 DataNode 發(fā)送復(fù)制或刪除數(shù)據(jù)塊的指令,這些指令只能由 Active NameNode 發(fā)送。
3.2 同一時(shí)刻只有一個(gè) Active NameNode
如果兩個(gè) NameNode 都是活躍狀態(tài),那么這個(gè)集群就會(huì)被分成2個(gè)小集群,它們都認(rèn)為自己是唯一活動(dòng)的集群。這就是著名的“腦裂”現(xiàn)象。
腦裂的 HDFS 集群很可能造成數(shù)據(jù)錯(cuò)亂、丟失數(shù)據(jù)塊,還可能向 DataNode 下發(fā)錯(cuò)誤的指令,這些錯(cuò)誤都很難恢復(fù)。
4 - HDFS 高可用的實(shí)現(xiàn)原理
這里主要介紹通過(guò)隔離(fencing)和 Quorum Journal Manager(QJM)共享存儲(chǔ)實(shí)現(xiàn)的 HDFS 高可用。
4.1 隔離(Fencing)- 預(yù)防腦裂
預(yù)防腦裂的常見(jiàn)方案就是 Fencing,即隔離,思路是把舊的 Active NameNode 隔離起來(lái),使它不能正常對(duì)外提供服務(wù),使集群在任何時(shí)候都只有一個(gè) Active NameNode。
HDFS 提供了 3 個(gè)級(jí)別的隔離(Fencing):
1)共享存儲(chǔ)隔離:同一時(shí)間只允許一個(gè) NameNode 向 JournalNode 寫(xiě)入 EditLog 數(shù)據(jù)。
2)客戶端隔離:同一時(shí)間只允許一個(gè) NameNode 可以響應(yīng)客戶端的請(qǐng)求。
3)DataNode 隔離:同一時(shí)間只允許一個(gè) NameNode 向 DataNode 下發(fā)命名空間相關(guān)的命令,例如刪除塊,復(fù)制塊等。
4.2 Qurom Journal Manager 共享存儲(chǔ)
在 HDFS 的 HA 架構(gòu)中還有一個(gè)非常重要的部分:Active NameNode 和 Standby NameNode 之間如何共享 EditLog 文件。
解決思路是:Active NameNode 將日志文件寫(xiě)到共享存儲(chǔ)上,Standby NameNode 實(shí)時(shí)地從共享存儲(chǔ)讀取 EditLog 文件,然后合并到 Standby NameNode 的命名空間中。一旦 Active NameNode 發(fā)生錯(cuò)誤,Standby NameNode 就可以立即切換到Active狀態(tài)。
HDFS 2.6 開(kāi)始,提供了一個(gè)叫做 Qurom Journal Manager(QJM)的共享存儲(chǔ)方案,來(lái)解決 HA 架構(gòu)中元數(shù)據(jù)的共享存儲(chǔ)問(wèn)題。
QJM 基于 Paxos 算法實(shí)現(xiàn),基本原理是:HDFS 集群中有 2n+1 臺(tái) JournalNode,EditLog 保存在 JN 的本地磁盤(pán)上;
每個(gè) JournalNode 都允許 NmaeNode 通過(guò)它的 RPC 接口讀寫(xiě) EditLog 文件;
當(dāng) NmaeNode 向共享存儲(chǔ)寫(xiě)入 EditLog 文件時(shí),它會(huì)通過(guò) QJM 向集群中所有的 JournalNode 并行發(fā)送寫(xiě) EditLog 文件的請(qǐng)求,當(dāng)有一半以上(>=n+1)的 JN 返回寫(xiě)操作成功時(shí),就認(rèn)為這次寫(xiě)操作成功了。
每次寫(xiě)數(shù)據(jù)操作有多數(shù)(>=n+1)JN 返回成功,就認(rèn)為這次寫(xiě)操作成功了。
由此我們可以知道,這個(gè) QJM 必須也是高可用的,否則 HDFS 的高可用就無(wú)法保障。
QJM 實(shí)現(xiàn) HA 的主要好處:
- 不存在單點(diǎn)故障問(wèn)題;
- 不需要配置額外的共享存儲(chǔ),降低了復(fù)雜度和維護(hù)成本;
- 不需要單獨(dú)配置 Fencing 實(shí)現(xiàn)(見(jiàn)文末#5.1節(jié)),因?yàn)?QJM 本身就內(nèi)置了 Fencing 的功能;
- 系統(tǒng)的魯棒性程度是可配置的( QJM 基于 Paxos 算法,配置 2n+1 臺(tái) JournalNode,最多能容忍 n 臺(tái)機(jī)器同時(shí)掛掉);
- QJM 中存儲(chǔ)日志的 JournalNode 不會(huì)因?yàn)槠渲幸慌_(tái)的延遲而影響整體的延遲,而且也不會(huì)因?yàn)?JournalNode 的數(shù)量增多而影響性能(因?yàn)?NameNode 向 JournalNode 發(fā)送日志是并行的)。
關(guān)于 QJM 的具體工作原理,后面有機(jī)會(huì)了專門(mén)講講。
5 - 其他補(bǔ)充
5.1 QJM 的 Fencing 方案
QJM 的 Fencing 只能讓原來(lái)的 Active NN 失去對(duì) JN 的寫(xiě)權(quán)限,但是原來(lái)的 Active NN 還是可以響應(yīng)客戶端的請(qǐng)求,對(duì) DataNode 進(jìn)行讀操作。
對(duì)客戶端和 DataNode 的隔離是通過(guò)配置 dfs.ha.fencing.methods 實(shí)現(xiàn)的,Hadoop 公共庫(kù)中有兩種 Fencing 實(shí)現(xiàn):
shell:即執(zhí)行一個(gè)用戶事先定義的 shell 命令或腳本來(lái)完成隔離。
sshfence:ssh 到原 Active NN 上,使用 fuser 結(jié)束進(jìn)程(通過(guò) TCP 端口號(hào)定位進(jìn)程 pid,比 jps 命令更準(zhǔn)確)。
5.2 - HDFS 高可用組件簡(jiǎn)介
5.2.1 ZKFailoverController
是基于 ZooKeeper 的故障轉(zhuǎn)移控制器,它負(fù)責(zé)控制 NameNode 的主備切換,ZKFailoverController 會(huì)監(jiān)測(cè)NameNode 的健康狀態(tài),當(dāng)發(fā)現(xiàn) Active NameNode 出現(xiàn)異常時(shí)會(huì)通過(guò) ZooKeeper 進(jìn)行一次新的選舉,完成 Active 和 Standby 狀態(tài)的切換。
5.2.2 HealthMonitor
周期性調(diào)用 NameNode 的 HAServiceProtocol RPC 接口(monitorHealth 和 getServiceStatus),監(jiān)控 NameNode 的健康狀態(tài)并向 ZKFailoverController 反饋。
5.2.3 ActiveStandbyElector
接收 ZKFailoverController 的選舉請(qǐng)求,通過(guò) ZooKeeper 自動(dòng)完成主備選舉,選舉完成后回調(diào) ZKFailoverController 的主備切換方法對(duì) NameNode 進(jìn)行 Active 和 Standby 狀態(tài)的切換。
參考資料
//www.dbjr.com.cn/article/220423.htm
//www.dbjr.com.cn/article/220415.htm
以上就是Hadoop NameNode高可用機(jī)制的詳細(xì)內(nèi)容,更多關(guān)于Hadoop NameNode高可用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java?ClassLoader虛擬類(lèi)實(shí)現(xiàn)代碼熱替換的示例代碼
本文主要介紹了Java?ClassLoader虛擬類(lèi)實(shí)現(xiàn)代碼熱替換的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06如何實(shí)現(xiàn)在IDEA中導(dǎo)入一個(gè)模塊
這篇文章主要介紹了如何實(shí)現(xiàn)在IDEA中導(dǎo)入一個(gè)模塊方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04java用split分割字符串的一個(gè)有趣現(xiàn)象
最近在項(xiàng)目中使用了java中的split分割字符串,發(fā)現(xiàn)了一個(gè)bug,充分了展示了自己對(duì)java底層的認(rèn)知有很多的不足和欠缺。下面將這次的經(jīng)過(guò)總結(jié)出來(lái)分享給大家,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2016-12-12SpringBoot動(dòng)態(tài)定時(shí)任務(wù)實(shí)現(xiàn)與應(yīng)用詳解
定時(shí)任務(wù)在許多應(yīng)用場(chǎng)景中是必不可少的,特別是在自動(dòng)化任務(wù)執(zhí)行、定期數(shù)據(jù)處理等方面,定時(shí)任務(wù)能極大地提高系統(tǒng)的效率,然而,隨著業(yè)務(wù)需求的變化,定時(shí)任務(wù)的執(zhí)行頻率或時(shí)間點(diǎn)可能需要?jiǎng)討B(tài)調(diào)整,所以本文給大家介紹了SpringBoot動(dòng)態(tài)定時(shí)任務(wù)實(shí)現(xiàn)與應(yīng)用2024-08-08Java異常處理之try...catch...語(yǔ)句的使用進(jìn)階
這篇文章主要介紹了Java異常處理之try...catch...語(yǔ)句的使用進(jìn)階,重點(diǎn)在于牽扯相關(guān)IO使用時(shí)的資源調(diào)配情況,需要的朋友可以參考下2015-11-11