Hadoop 2.0是怎樣產(chǎn)生的慨蓝?早期的hadoop版本,NN(namenode)是HDFS集群的單點故障點雹嗦,每一個集群只有一個NN,如果這個機(jī)器或進(jìn)程不可用啥酱,整個集群就無法使用。為了解決這個問題南誊,出現(xiàn)了一堆針對HDFS HA的解決方案(如:Linux HA, VMware FT, shared NAS+NFS, BookKeeper, QJM/Quorum Journal Manager, BackupNode等); 在HA具體實現(xiàn)方法不同的情況下身诺,HA框架的流程是一致的, 不一致的就是如何存儲和管理日志。在Active NN和Standby NN之間要有個共享的存儲日志的地方抄囚,Active NN把EditLog寫到這個共享的存儲日志的地方霉赡,Standby NN去讀取日志然后執(zhí)行,這樣Active和Standby NN內(nèi)存中的HDFS元數(shù)據(jù)保持著同步幔托。一旦發(fā)生主從切換Standby NN可以盡快接管Active NN的工作.
SPOF方案回顧
1. Secondary NameNode:它不是HA(高可用)穴亏,它只是階段性的合并edits和fsimage,以縮短集群啟動的時間。當(dāng)NN失效的時候嗓化,Secondary NN并無法立刻提供服務(wù)锅劝,Secondary NN甚至無法保證數(shù)據(jù)完整性:如果NN數(shù)據(jù)丟失的話,在上一次合并后的文件系統(tǒng)的改動會丟失
2. Backup NameNode (HADOOP-4539):它在內(nèi)存中復(fù)制了NN的當(dāng)前狀態(tài)蟆湖,算是Warm Standby故爵,可也就僅限于此,并沒有failover(故障切換)等隅津。它同樣是階段性的做checkpoint诬垂,也無法保證數(shù)據(jù)完整性
3. 手動把name.dir指向NFS(Network File System),這是安全的Cold Standby伦仍,可以保證元數(shù)據(jù)不丟失结窘,但集群的恢復(fù)則完全靠手動
4. Facebook AvatarNode:Facebook有強(qiáng)大的運維做后盾,所以Avatarnode只是Hot Standby充蓝,并沒有自動切換隧枫,當(dāng)主NN失效的時候,需要管理員確認(rèn)谓苟,然后手動把對外提供服務(wù)的虛擬IP映射到Standby NN官脓,這樣做的好處是確保不會發(fā)生腦裂的場景。其某些設(shè)計思想和Hadoop 2.0里的HA非常相似涝焙,從時間上來看卑笨,Hadoop 2.0應(yīng)該是借鑒了Facebook的做法
? Facebook AvatarNode 原理示例圖
? PrimaryNN與StandbyNN之間通過NFS來共享FsEdits固该、FsImage文件器腋,這樣主備NN之間就擁有了一致的目錄樹和block信息;而block的位置信息俭尖,可以根據(jù)DN向兩個NN上報的信息過程中構(gòu)建起來隧哮。這樣再輔以虛IP桶良,可以較好達(dá)到主備NN快速熱切的目的。但是顯然沮翔,這里的NFS又引入了新的SPOF(Single Points Of Failure:單點故障)
? 在主備NN共享元數(shù)據(jù)的過程中陨帆,也有方案通過主NN將FsEdits的內(nèi)容通過與備NN建立的網(wǎng)絡(luò)IO流,實時寫入備NN鉴竭,并且保證整個過程的原子性歧譬。這種方案,解決了NFS共享元數(shù)據(jù)引入的SPOF搏存,但是主備NN之間的網(wǎng)絡(luò)連接又會成為新的問題
hadoop2.X ha 原理:
? hadoop2.x之后瑰步,Clouera提出了QJM/Qurom Journal Manager,這是一個基于Paxos算法實現(xiàn)的HDFS HA方案璧眠,它給出了一種較好的解決思路和方案,示意圖如下:
? 基本原理就是用2N+1臺 JN 存儲EditLog缩焦,每次寫數(shù)據(jù)操作有大多數(shù)(>=N+1)返回成功時即認(rèn)為該次寫成功读虏,數(shù)據(jù)不會丟失了。當(dāng)然這個算法所能容忍的是最多有N臺機(jī)器掛掉袁滥,如果多于N臺掛掉盖桥,這個算法就失效了。這個原理是基于Paxos算法
? 在HA架構(gòu)里面SecondaryNameNode這個冷備角色已經(jīng)不存在了题翻,為了保持standby NN時時的與主Active NN的元數(shù)據(jù)保持一致揩徊,他們之間交互通過一系列守護(hù)的輕量級進(jìn)程JournalNode
? 任何修改操作在 Active NN上執(zhí)行時,JN進(jìn)程同時也會記錄修改log到至少半數(shù)以上的JN中嵌赠,這時 Standby NN 監(jiān)測到JN 里面的同步log發(fā)生變化了會讀取 JN 里面的修改log塑荒,然后同步到自己的的目錄鏡像樹里面,如下圖:
? 當(dāng)發(fā)生故障時姜挺,Active的 NN 掛掉后齿税,Standby NN 會在它成為Active NN 前,讀取所有的JN里面的修改日志炊豪,這樣就能高可靠的保證與掛掉的NN的目錄鏡像樹一致凌箕,然后無縫的接替它的職責(zé),維護(hù)來自客戶端請求词渤,從而達(dá)到一個高可用的目的
? QJM方式來實現(xiàn)HA的主要優(yōu)勢:
1. 不需要配置額外的高共享存儲牵舱,降低了復(fù)雜度和維護(hù)成本
2. 消除spof
3. 系統(tǒng)魯棒性(Robust:健壯)的程度是可配置(魯棒是Robust的音譯,也就是健壯和強(qiáng)壯的意思。它是在異常和危險情況下系統(tǒng)生存的關(guān)鍵)
4. JN不會因為其中一臺的延遲而影響整體的延遲掖肋,而且也不會因為JN的數(shù)量增多而影響性能(因為NN向JN發(fā)送日志是并行的)
hadoop2.x ha 詳述:
? datanode的fencing: 確保只有一個NN能命令DN仆葡。HDFS-1972中詳細(xì)描述了DN如何實現(xiàn)fencing
1. 每個NN改變狀態(tài)的時候,向DN發(fā)送自己的狀態(tài)和一個序列號
2. DN在運行過程中維護(hù)此序列號志笼,當(dāng)failover(故障切換)時,新的NN在返回DN心跳時會返回自己的active狀態(tài)和一個更大的序列號把篓。DN接收到這個返回則認(rèn)為該NN為新的active
3. 如果這時原來的active NN恢復(fù)纫溃,返回給DN的心跳信息包含active狀態(tài)和原來的序列號,這時DN就會拒絕這個NN的命令
? 客戶端fencing:確保只有一個NN能響應(yīng)客戶端請求韧掩,讓訪問standby nn的客戶端直接失敗紊浩。在RPC層封裝了一層,通過FailoverProxyProvider以重試的方式連接NN疗锐。通過若干次連接一個NN失敗后嘗試連接新的NN坊谁,對客戶端的影響是重試的時候增加一定的延遲』客戶端可以設(shè)置重試此時和時間
? Hadoop提供了ZKFailoverController角色口芍,部署在每個NameNode的節(jié)點上,作為一個deamon(守護(hù))進(jìn)程, 簡稱zkfc雇卷,示例圖如下:
? FailoverController主要包括三個組件:
1. HealthMonitor(健康監(jiān)測器): 監(jiān)控NameNode是否處于unavailable(不可用)或unhealthy(不健康)狀態(tài)鬓椭。當(dāng)前通過RPC調(diào)用NN相應(yīng)的方法完成
2. ActiveStandbyElector: 管理和監(jiān)控自己在ZK中的狀態(tài)
3. ZKFailoverController 它訂閱HealthMonitor 和ActiveStandbyElector 的事件颠猴,并管理NameNode的狀態(tài)
? ZKFailoverController主要職責(zé):
1. 健康監(jiān)測:周期性的向它監(jiān)控的NN發(fā)送健康探測命令,從而來確定某個NameNode是否處于健康狀態(tài)小染,如果機(jī)器宕機(jī)翘瓮,心跳失敗,那么zkfc就會標(biāo)記它處于一個不健康的狀態(tài)
2. 會話管理:如果NN是健康的裤翩,zkfc就會在zookeeper中保持一個打開的會話资盅,如果NameNode同時還是Active狀態(tài)的,那么zkfc還會在Zookeeper中占有一個類型為短暫類型的znode踊赠,當(dāng)這個NN掛掉時呵扛,這個znode將會被刪除,然后備用的NN臼疫,將會得到這把鎖择份,升級為主NN,同時標(biāo)記狀態(tài)為Active
3. 當(dāng)宕機(jī)的NN新啟動時烫堤,它會再次注冊zookeper荣赶,發(fā)現(xiàn)已經(jīng)有znode鎖了,便會自動變?yōu)镾tandby狀態(tài)鸽斟,如此往復(fù)循環(huán)拔创,保證高可靠,需要注意富蓄,目前僅僅支持最多配置2個NN
4. master選舉:如上所述剩燥,通過在zookeeper中維持一個短暫類型的znode,來實現(xiàn)搶占式的鎖機(jī)制立倍,從而判斷那個NameNode為Active狀態(tài)