一、HA架構工作背景
HDFS集群中的nameNode存在單點故障因素。對于只有一個nameNode工作的集群來說,一旦nameNode出現(xiàn)意外情況,會導致整個集群無法工作,直到nameNode重新啟動。
為了解決上述問題,Hadoop給出了高容錯,高可用的HA方案:一個HDFS集群至少存在兩個nameNode,一個nameNode處在active(主)狀態(tài),其他nameNode處在standby(備)狀態(tài)。一旦處于activate狀態(tài)的nameNode發(fā)生意外,其他處于standby狀態(tài)的nameNode立即搶占activate的臨時節(jié)點,代替發(fā)生意外的nameNode繼續(xù)對外提供服務,從而保證了整個HDFS集群處在正常工作狀態(tài)。
二、主備數(shù)據(jù)同步
想要備nameNode接替主nameNode工作,那么必須保證備nameNode和主nameNode擁有相同的內存數(shù)據(jù)。
主nameNode主要有以下數(shù)據(jù)需要進行頻繁同步:edits log(日志)、block列表信息以及DataNode心跳檢測
2.1首先說日志的同步:
同步edits log數(shù)據(jù)是借助第三方JNN( Journal Nodes )提供的服務。客戶端對主nameNode操作,主nameNode將edits log寫到JNN集群,備nameNode從JNN集群上讀取數(shù)據(jù),同步內存數(shù)據(jù)。可是主nameNode發(fā)生意外,導致JNN集群上各服務器上的數(shù)據(jù)不一致怎么辦呢?JNN集群最少有三臺服務器,一旦JNN服務器上的數(shù)據(jù)不一致,立即進行投票選舉,通過過半機制保證數(shù)據(jù)的一致性(即以多數(shù)為準),舍掉與多數(shù)不一致的數(shù)據(jù),然后在將數(shù)據(jù)同步給舍掉數(shù)據(jù)的服務器,保證了數(shù)據(jù)的一致性。
2.2、介紹一下JNN
JNN的過半機制:
如果主nameNode向三臺JNN寫數(shù)據(jù),只要保證過半JNN寫成功,就返回成功, JNN根據(jù)過半機制,進行數(shù)據(jù)在三臺JNN上同步。
最終一致性:最終三臺JNN上的edits信息是一致的。
JNN上的edits只能有一臺nameNode寫信息,防止腦裂。
2.3、block列表的同步:
DataNode主動向各臺nameNode發(fā)送block列表信息和心跳。從而保證了主備之間block的一致性。
2.4、合并fsimages與edits
原來HDFS上的secondarynameNode的合并fsimages(鏡像)與edits(日志) 文件的工作,現(xiàn)在交給備nameNode進行,備用nameNode一小時合并一次并推送給主nameNode,在不滿一小時的情況下,如果edits文件的操作達到100w,也要進行合并。
三、自動切換nameNode
主nameNode和備nameNode的切換時自動切換的,通過zookeeper集群來完成!
首先添加zookeeper集群,在每個nameNode上運行一個zkfc進程(zkfc是zookeeper的客戶端)。zkfc要和zookeeper集群保持長連接和心跳。
在集群啟動的時候,兩個NameNode都處于standby狀態(tài), 兩個nameNode的各自的zkfc要向zookeeper集群搶占創(chuàng)建一個臨時節(jié)點,該臨時節(jié)點保存了主nameNode的信息,哪個zkfc創(chuàng)建成功,則哪個zkfc所在主機上的nameNode為主nameNode。
nameNode上的zkfc要監(jiān)控主nameNode創(chuàng)建的臨時節(jié)點,一旦主nameNode出現(xiàn)故障,zkfc將刪除該臨時節(jié)點(實際上是因為主nameNode上的zkfc不能和zookeeper集群保持心跳連接,臨時節(jié)點消失),臨時節(jié)點消失,則備nameNode上的zkfc要向zookeeper集群搶占創(chuàng)建臨時節(jié)點,如果創(chuàng)建成功,備nameNode升級為主nameNode。
在備份nameNode升級為主nameNode之前,要和原來的nameNode通信,確保原來的nameNode已經不能提供服務。如果原來的nameNode是由于網絡延遲等原因導致的臨時節(jié)點消失(也就是說還能提供服務),則殺死原來的nameNode。