HDFS單點故障和線性擴展問題

這篇文章寫的很優(yōu)秀咬清,然后自己稍微整理了下旧烧。轉(zhuǎn)自:https://matt33.com/2018/07/15/hdfs-architecture-learn/

1、HDFS 1.0 的問題

在前面的介紹中夺谁,關(guān)于 HDFS1.0 的架構(gòu)匾鸥,首先都會看到 NameNode 的單點問題扫腺,這個在生產(chǎn)環(huán)境中是非常要命的問題笆环,早期的 HDFS 由于規(guī)模較小躁劣,有些問題就被隱藏了志膀,但自從進入了移動互聯(lián)網(wǎng)時代溉浙,很多公司都開始進入了 PB 級的大數(shù)據(jù)時代戳稽,HDFS 1.0的設(shè)計缺陷已經(jīng)無法滿足生產(chǎn)的需求,最致命的問題有以下兩點:

  • NameNode 的單點問題颂郎,如果 NameNode 掛掉了,數(shù)據(jù)讀寫都會受到影響竭缝,HDFS 整體將變得不可用,這在生產(chǎn)環(huán)境中是不可接受的耿戚;

技術(shù)難點:如何保持主備NameNode的狀態(tài)同步,并讓Standby在Active掛掉后迅速提供服務(wù)皂股,NameNode啟動比較耗時呜呐,包括FSimage和Editlog(獲取file to block)洋机,處理所有DataNode第一次blockreport(獲取block to DataNode信息)绷旗,保持NN的狀態(tài)同步衔肢,需要這兩部信息同步膀懈。

  • 水平擴展問題,隨著集群規(guī)模的擴大胳赌,1.0 時集群規(guī)模達到3000時疑苫,會導致整個集群管理的文件數(shù)目達到上限(因為 NameNode 要管理整個集群 block 元信息、數(shù)據(jù)目錄信息等)挺勿。

為了解決上面的兩個問題,Hadoop2.0 提供一套統(tǒng)一的解決方案:

  • 1蚊丐、HA(High Availability 高可用方案):這個是為了解決 NameNode 單點問題;
  • 2凛篙、NameNode Federation:是用來解決 HDFS 集群的線性擴展能力膀捷。

2、HDFS 2.0 的 HA 實現(xiàn)

關(guān)于 HDFS 高可用方案壶笼,非常推薦這篇文章:Hadoop NameNode 高可用 (High Availability) 實現(xiàn)解析,IBM 博客的質(zhì)量確實很高,這部分我這里也是主要根據(jù)這篇文章做一個總結(jié)坤候,這里會從問題的原因、如何解決的角度去總結(jié)徒河,并不會深入源碼的實現(xiàn)細節(jié),想有更深入了解還是推薦上面文章。

這里先看下 HDFS 高可用解決方案的架構(gòu)設(shè)計,如下圖(下圖來自上面的文章)所示:

754a25160047149592b9d6b979a8f6bd

這里與前面 1.0 的架構(gòu)已經(jīng)有很大變化,簡單介紹一下上面的組件:

  • 1、Active NameNode(ANN)Standby NameNode(SNN):兩臺 NameNode 形成互備,一臺處于 Active 狀態(tài)贬堵,為主 NameNode松忍,另外一臺處于 Standby 狀態(tài)宏所,為備 NameNode更扁,只有主 NameNode 才能對外提供讀寫服務(wù)溃列;
  • 2哄啄、ZKFailoverController(主備切換控制器沪么,F(xiàn)C):ZKFailoverController 作為獨立的進程運行,對 NameNode 的主備切換進行總體控制州胳。ZKFailoverController 能及時檢測到 NameNode 的健康狀況碗硬,在主 NameNode 故障時借助 Zookeeper 實現(xiàn)自動的主備選舉和切換(當然 NameNode 目前也支持不依賴于 Zookeeper 的手動主備切換);
  • 3、Zookeeper 集群:為主備切換控制器提供主備選舉支持;
  • 4、共享存儲系統(tǒng):共享存儲系統(tǒng)是實現(xiàn) NameNode 的高可用最為關(guān)鍵的部分搀罢,共享存儲系統(tǒng)保存了 NameNode 在運行過程中所產(chǎn)生的 HDFS 的元數(shù)據(jù)榔至。主 NameNode 和備 NameNode 通過共享存儲系統(tǒng)實現(xiàn)元數(shù)據(jù)同步抵赢。在進行主備切換的時候,新的主 NameNode 在確認元數(shù)據(jù)完全同步之后才能繼續(xù)對外提供服務(wù)唧取。
  • 5铅鲤、DataNode 節(jié)點:因為主 NameNode 和備 NameNode 需要共享 HDFS 的數(shù)據(jù)塊和 DataNode 之間的映射關(guān)系,為了使故障切換能夠快速進行枫弟,DataNode 會同時向主 NameNode 和備 NameNode 上報數(shù)據(jù)塊的位置信息邢享。

3、FailoverController

FC 最初的目的是為了實現(xiàn) SNN 和 ANN 之間故障自動切換淡诗,F(xiàn)C 是獨立與 NN 之外的故障切換控制器驼仪,ZKFC 作為 NameNode 機器上一個獨立的進程啟動 掸犬,它啟動的時候會創(chuàng)建 HealthMonitorActiveStandbyElector這兩個主要的內(nèi)部組件袜漩,其中:

  1. HealthMonitor:主要負責檢測 NameNode 的健康狀態(tài)绪爸,如果檢測到 NameNode 的狀態(tài)發(fā)生變化,會回調(diào) ZKFailoverController 的相應(yīng)方法進行自動的主備選舉宙攻;
  2. ActiveStandbyElector:主要負責完成自動的主備選舉奠货,內(nèi)部封裝了 Zookeeper 的處理邏輯,一旦 Zookeeper 主備選舉完成座掘,會回調(diào) ZKFailoverController 的相應(yīng)方法來進行 NameNode 的主備狀態(tài)切換递惋。
img

4 、自動觸發(fā)主備選舉

NameNode 在選舉成功后溢陪,會在 zk 上創(chuàng)建了一個 /hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock 節(jié)點萍虽,而沒有選舉成功的備 NameNode 會監(jiān)控這個節(jié)點,通過 Watcher 來監(jiān)聽這個節(jié)點的狀態(tài)變化事件形真,ZKFC 的 ActiveStandbyElector 主要關(guān)注這個節(jié)點的 NodeDeleted 事件(這部分實現(xiàn)跟 Kafka 中 Controller 的選舉一樣)杉编。

如果 Active NameNode 對應(yīng)的 HealthMonitor 檢測到 NameNode 的狀態(tài)異常時, ZKFailoverController 會主動刪除當前在 Zookeeper 上建立的臨時節(jié)點 /hadoop-ha/{dfs.nameservices}/ActiveStandbyElectorLock咆霜,這樣處于 Standby 狀態(tài)的 NameNode 的 ActiveStandbyElector 注冊的監(jiān)聽器就會收到這個節(jié)點的 NodeDeleted 事件邓馒。收到這個事件之后,會馬上再次進入到創(chuàng)建 /hadoop-ha/{dfs.nameservices}/ActiveStandbyElectorLock 節(jié)點的流程蛾坯,如果創(chuàng)建成功光酣,這個本來處于 Standby 狀態(tài)的 NameNode 就選舉為主 NameNode 并隨后開始切換為 Active 狀態(tài)。

當然脉课,如果是 Active 狀態(tài)的 NameNode 所在的機器整個宕掉的話救军,那么根據(jù) Zookeeper 的臨時節(jié)點特性,/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock 節(jié)點會自動被刪除倘零,從而也會自動進行一次主備切換唱遭。

5、HDFS 腦裂(split-brain)問題

在實際中视事,NameNode 可能會出現(xiàn)這種情況胆萧,NameNode 在垃圾回收(GC)時,可能會在長時間內(nèi)整個系統(tǒng)無響應(yīng)俐东,因此跌穗,也就無法向 zk 寫入心跳信息,這樣的話可能會導致臨時節(jié)點掉線虏辫,備 NameNode 會切換到 Active 狀態(tài)蚌吸,這種情況,可能會導致整個集群會有同時有兩個 NameNode砌庄,這就是腦裂問題羹唠。

腦裂問題的解決方案是隔離(Fencing)奕枢,主要是在以下三處采用隔離措施:

  • 1、第三方共享存儲:任一時刻佩微,只有一個 NN 可以寫入缝彬;
  • 2、DataNode:需要保證只有一個 NN 發(fā)出與管理數(shù)據(jù)副本有關(guān)的刪除命令哺眯;
  • 3谷浅、Client:需要保證同一時刻只有一個 NN 能夠?qū)?Client 的請求發(fā)出正確的響應(yīng)。

關(guān)于這個問題目前解決方案的實現(xiàn)如下:

  1. ActiveStandbyElector 為了實現(xiàn) fencing奶卓,會在成功創(chuàng)建 Zookeeper 節(jié)點 hadoop-ha/{dfs.nameservices}/ActiveStandbyElectorLock 從而成為 Active NameNode 之后一疯,創(chuàng)建另外一個路徑為 /hadoop-ha/${dfs.nameservices}/ActiveBreadCrumb 的持久節(jié)點,這個節(jié)點里面保存了這個 Active NameNode 的地址信息夺姑;
  2. Active NameNode 的 ActiveStandbyElector 在正常的狀態(tài)下關(guān)閉 Zookeeper Session 的時候墩邀,會一起刪除這個持久節(jié)點;
  3. 但如果 ActiveStandbyElector 在異常的狀態(tài)下 Zookeeper Session 關(guān)閉 (比如前述的 Zookeeper 假死)盏浙,那么由于 /hadoop-ha/${dfs.nameservices}/ActiveBreadCrumb 是持久節(jié)點眉睹,會一直保留下來,后面當另一個 NameNode 選主成功之后只盹,會注意到上一個 Active NameNode 遺留下來的這個節(jié)點辣往,從而會回調(diào) ZKFailoverController 的方法對舊的 Active NameNode 進行 fencing。

在進行 fencing 的時候殖卑,會執(zhí)行以下的操作:

  • 1站削、首先嘗試調(diào)用這個舊 Active NameNode 的 HAServiceProtocol RPC 接口的 transitionToStandby 方法,看能不能把它轉(zhuǎn)換為 Standby 狀態(tài)孵稽;
  • 2许起、如果 transitionToStandby 方法調(diào)用失敗,那么就執(zhí)行 Hadoop 配置文件之中預定義的隔離措施菩鲜。

Hadoop 目前主要提供兩種隔離措施园细,通常會選擇第一種:

  • 1、sshfence:通過 SSH 登錄到目標機器上接校,執(zhí)行命令 fuser 將對應(yīng)的進程殺死猛频;
  • 2、shellfence:執(zhí)行一個用戶自定義的 shell 腳本來將對應(yīng)的進程隔離蛛勉。

只有在成功地執(zhí)行完成 fencing 之后鹿寻,選主成功的 ActiveStandbyElector 才會回調(diào) ZKFailoverController 的 becomeActive 方法將對應(yīng)的 NameNode 轉(zhuǎn)換為 Active 狀態(tài),開始對外提供服務(wù)诽凌。

NameNode 選舉的實現(xiàn)機制與 Kafka 的 Controller 類似毡熏,那么 Kafka 是如何避免腦裂問題的呢?

  • 1侣诵、Controller 給 Broker 發(fā)送的請求中痢法,都會攜帶 controller epoch 信息狱窘,如果 broker 發(fā)現(xiàn)當前請求的 epoch 小于緩存中的值,那么就證明這是來自舊 Controller 的請求财搁,就會決絕這個請求蘸炸,正常情況下是沒什么問題的;
  • 2妇拯、但是異常情況下呢幻馁?如果 Broker 先收到異常 Controller 的請求進行處理呢?現(xiàn)在看 Kafka 在這一部分并沒有適合的方案越锈;
  • 3、正常情況下膘滨,Kafka 新的 Controller 選舉出來之后甘凭,Controller 會向全局所有 broker 發(fā)送一個 metadata 請求,這樣全局所有 Broker 都可以知道當前最新的 controller epoch火邓,但是并不能保證可以完全避免上面這個問題丹弱,還是有出現(xiàn)這個問題的幾率的,只不過非常小铲咨,而且即使出現(xiàn)了由于 Kafka 的高可靠架構(gòu)躲胳,影響也非常有限,至少從目前看纤勒,這個問題并不是嚴重的問題坯苹。

6、第三方存儲(共享存儲)

上述 HA 方案還有一個明顯缺點摇天,那就是第三方存儲節(jié)點有可能失效粹湃,之前有很多共享存儲的實現(xiàn)方案,目前社區(qū)已經(jīng)把由 Clouderea 公司實現(xiàn)的基于 QJM 的方案合并到 HDFS 的 trunk 之中并且作為默認的共享存儲實現(xiàn)泉坐,本部分只針對基于 QJM 的共享存儲方案的內(nèi)部實現(xiàn)原理進行分析为鳄。

QJM(Quorum Journal Manager)本質(zhì)上是利用 Paxos 協(xié)議來實現(xiàn)的,QJM 在 2F+1 個 JournalNode 上存儲 NN 的 editlog嗦锐,每次寫入操作都通過 Paxos 保證寫入的一致性祖今,它最多可以允許有 F 個 JournalNode 節(jié)點同時故障挨务,其實現(xiàn)如下(圖片來自:Hadoop NameNode 高可用 (High Availability) 實現(xiàn)解析 ):

image-20191109225330735

基于 QJM 的共享存儲的數(shù)據(jù)同步機制

Active NameNode 首先把 EditLog 提交到 JournalNode 集群,然后 Standby NameNode 再從 JournalNode 集群定時同步 EditLog偏形。

還有一點需要注意的是,在 2.0 中不再有 SNN 這個角色了液南,NameNode 在啟動后壳猜,會先加載 FSImage 文件和共享目錄上的 EditLog Segment 文件滑凉,之后 NameNode 會啟動 EditLogTailer 線程和 StandbyCheckpointer 線程统扳,正式進入 Standby 模式喘帚,其中:

  • 1、EditLogTailer 線程的作用是定時從 JournalNode 集群上同步 EditLog咒钟;
  • 2吹由、StandbyCheckpointer 線程的作用其實是為了替代 Hadoop 1.x 版本之中的 Secondary NameNode 的功能,StandbyCheckpointer 線程會在 Standby NameNode 節(jié)點上定期進行 Checkpoint朱嘴,將 Checkpoint 之后的 FSImage 文件上傳到 Active NameNode 節(jié)點倾鲫。

7、HDFS 2.0 Federation 實現(xiàn)

在 1.0 中萍嬉,HDFS 的架構(gòu)設(shè)計有以下缺點:

  • 1乌昔、namespace 擴展性差:在單一的 NN 情況下,因為所有 namespace 數(shù)據(jù)都需要加載到內(nèi)存壤追,所以物理機內(nèi)存的大小限制了整個 HDFS 能夠容納文件的最大個數(shù)(namespace 指的是 HDFS 中樹形目錄和文件結(jié)構(gòu)以及文件對應(yīng)的 block 信息)磕道;
  • 2、性能可擴展性差:由于所有請求都需要經(jīng)過 NN行冰,單一 NN 導致所有請求都由一臺機器進行處理溺蕉,很容易達到單臺機器的吞吐;
  • 3悼做、隔離性差:多租戶的情況下疯特,單一 NN 的架構(gòu)無法在租戶間進行隔離,會造成不可避免的相互影響肛走。

而 Federation 的設(shè)計就是為了解決這些問題漓雅,采用 Federation 的最主要原因是設(shè)計實現(xiàn)簡單,而且還能解決問題羹与。

8故硅、Federation 架構(gòu)

Federation 的架構(gòu)設(shè)計如下圖所示(圖片來自 HDFS Federation):

image-20191109225426086

Federation 的核心設(shè)計思想

Federation的核心思想是將一個大的 namespace 劃分多個子 namespace,并且每個 namespace 分別由單獨的 NameNode 負責纵搁,這些 NameNode 之間互相獨立吃衅,不會影響,不需要做任何協(xié)調(diào)工作(其實跟拆集群有一些相似)腾誉,集群的所有 DataNode 會被多個 NameNode 共享徘层。

其中,每個子 namespace 和 DataNode 之間會由數(shù)據(jù)塊管理層作為中介建立映射關(guān)系利职,數(shù)據(jù)塊管理層由若干數(shù)據(jù)塊池(Pool)構(gòu)成趣效,每個數(shù)據(jù)塊只會唯一屬于某個固定的數(shù)據(jù)塊池,而一個子 namespace 可以對應(yīng)多個數(shù)據(jù)塊池猪贪。每個 DataNode 需要向集群中所有的 NameNode 注冊跷敬,且周期性地向所有 NameNode 發(fā)送心跳和塊報告,并執(zhí)行來自所有 NameNode 的命令热押。

  • 一個 block pool 由屬于同一個 namespace 的數(shù)據(jù)塊組成西傀,每個 DataNode 可能會存儲集群中所有 block pool 的數(shù)據(jù)塊斤寇;
  • 每個 block pool 內(nèi)部自治,也就是說各自管理各自的 block拥褂,不會與其他 block pool 交流娘锁,如果一個 NameNode 掛掉了,不會影響其他 NameNode;
  • 某個 NameNode 上的 namespace 和它對應(yīng)的 block pool 一起被稱為 namespace volume饺鹃,它是管理的基本單位莫秆。當一個 NameNode/namespace 被刪除后,其所有 DataNode 上對應(yīng)的 block pool 也會被刪除悔详,當集群升級時镊屎,每個 namespace volume 可以作為一個基本單元進行升級。

到這里伟端,基本對 HDFS 這部分總結(jié)完了杯道,雖然文章的內(nèi)容基本都來自下面的參考資料,但是自己在總結(jié)的過程中责蝠,也對 HDFS 的基本架構(gòu)有一定的了解,后續(xù)結(jié)合公司 HDFS 團隊的 CaseStudy 深入學習這部分的內(nèi)容萎庭,工作中霜医,也慢慢感覺到分布式系統(tǒng),很多的設(shè)計實現(xiàn)與問題解決方案都很類似驳规,只不過因為面對業(yè)務(wù)場景的不同而采用了不同的實現(xiàn)肴敛。

9、參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市埠偿,隨后出現(xiàn)的幾起案子透罢,更是在濱河造成了極大的恐慌,老刑警劉巖冠蒋,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件羽圃,死亡現(xiàn)場離奇詭異,居然都是意外死亡抖剿,警方通過查閱死者的電腦和手機朽寞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門识窿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人愁憔,你說我怎么就攤上這事腕扶。” “怎么了吨掌?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵半抱,是天一觀的道長。 經(jīng)常有香客問我膜宋,道長窿侈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任秋茫,我火速辦了婚禮史简,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肛著。我一直安慰自己圆兵,他們只是感情好,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布枢贿。 她就那樣靜靜地躺著殉农,像睡著了一般。 火紅的嫁衣襯著肌膚如雪局荚。 梳的紋絲不亂的頭發(fā)上超凳,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音耀态,去河邊找鬼轮傍。 笑死,一個胖子當著我的面吹牛首装,可吹牛的內(nèi)容都是我干的创夜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼簿盅,長吁一口氣:“原來是場噩夢啊……” “哼挥下!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起桨醋,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤棚瘟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后喜最,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體偎蘸,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了迷雪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片限书。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖章咧,靈堂內(nèi)的尸體忽然破棺而出倦西,到底是詐尸還是另有隱情,我是刑警寧澤赁严,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布扰柠,位于F島的核電站,受9級特大地震影響疼约,放射性物質(zhì)發(fā)生泄漏卤档。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一程剥、第九天 我趴在偏房一處隱蔽的房頂上張望劝枣。 院中可真熱鬧,春花似錦织鲸、人聲如沸舔腾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽琢唾。三九已至,卻和暖如春盾饮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背懒熙。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工丘损, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人工扎。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓徘钥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親肢娘。 傳聞我的和親對象是個殘疾皇子呈础,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容