都2022年了,HDFS為何還如此能戰
本文分享自華為雲社群《HDFS為何在大資料領域經久不衰?》,作者: JavaEdge。
1 概述
1.1 簡介
- Hadoop實現的一個分散式檔案系統(Hadoop Distributed File System),簡稱HDFS
- 源自於Google的GFS論文,發表於2003年,HDFS是GFS的克隆版
大資料中最寶貴、最難以代替的就是資料,一切都圍繞資料。
HDFS是最早的大資料儲存系統,儲存著寶貴的資料資產,各種新演算法、框架要想得到廣泛使用,必須支援HDFS,才能獲取已儲存在裡面的資料。所以大資料技術越發展,新技術越多,HDFS得到的支援越多,越離不開HDFS。HDFS也許不是最好的大資料儲存技術,但依然是最重要的大資料儲存技術。
HDFS是如何實現大資料高速、可靠的儲存和訪問的呢?
Hadoop分散式檔案系統HDFS的設計目標是管理數以千計的伺服器、數以萬計的磁碟,將大規模的伺服器計算資源當作一個單一儲存系統進行管理,對應用程式提供數以PB計的儲存容量,讓應用程式像使用普通檔案系統一樣儲存大規模的檔案資料。
1.2 設計目標
檔案以多副本的方式進行儲存:
filel:node1 node2 node3
file2: node2 node3 node4
file3: node3 node4 node5
file4: node5 node6 node7
缺點:
- 不管檔案多大,都儲存在一個節點,在進行資料處理時,很難進行並行處理,節點可能就成為網路瓶頸,很難進行大資料的處理
- 儲存負載很難均衡,每個節點的利用率很低
優點:
- 巨大的分散式檔案系統
- 執行在普通廉價的硬體
- 易擴充套件、為使用者提供效能不錯的檔案儲存服務
2 如何設計一個分散式檔案系統
HDFS的大容量儲存和高速訪問的實現。
RAID將資料分片後,在多塊磁碟上併發進行讀寫訪問,提高了儲存容量、加快了訪問速度,並通過資料冗餘校驗提高了資料可靠性,即使某塊磁碟損壞也不會丟資料。將RAID的設計理念擴大到整個分散式伺服器叢集,就產生了分散式檔案系統,這便是Hadoop分散式檔案系統的核心原理。
和RAID在多個磁碟上進行檔案儲存及並行讀寫的思路一樣,HDFS是在一個大規模分散式伺服器叢集上,對資料分片後進行並行讀寫及冗餘儲存。因為HDFS可部署在一個大的伺服器叢集,叢集中所有伺服器的磁碟都可供HDFS使用,所以整個HDFS的儲存空間可以達到PB級。
HDFS是主從架構。一個HDFS叢集會有一個NameNode(命名節點,簡稱NN),作為主伺服器(master server)。
- NameNode用於管理檔案系統的名稱空間以及調節客戶訪問檔案
- 還有多個DataNode(簡稱DN),資料節點,作為從節點(slave server)存在
- 通常每個叢集中的DataNode,都會被NameNode所管理,DataNode用於儲存資料
HDFS公開了檔案系統名稱空間,允許使用者將資料儲存在檔案中,就好比我們平時使用os中的檔案系統一樣,使用者無需關心底層是如何儲存資料的。 在底層,一個檔案會被分成一或多個數據塊,這些資料庫塊會被儲存在一組資料節點中。在CDH中資料塊的預設128M。 在NameNode,可執行檔案系統的名稱空間操作,如開啟,關閉,重新命名檔案等。這也決定了資料塊到資料節點的對映。
HDFS被設計為可執行在普通的廉價機器上,而這些機器通常執行著一個Linux作業系統。一個典型的HDFS叢集部署會有一個專門的機器只能執行NameNode
,而其他叢集中的機器各自執行一個DataNode
例項。雖然一臺機器上也可以執行多個節點,但不推薦。
DataNode
- 儲存使用者的檔案對應的資料塊(Block)
- 會定期向NN傳送心跳資訊,彙報本身及其所有的block資訊和健康狀況
負責檔案資料的儲存和讀寫操作,HDFS將檔案資料分割成若干資料塊(Block),每個DataNode儲存一部分Block,這樣檔案就分佈儲存在整個HDFS伺服器叢集中。
應用程式客戶端(Client)可並行訪問這些Block,從而使得HDFS可以在伺服器叢集規模上實現資料並行訪問,極大提高訪問速度。
HDFS叢集的DataNode伺服器會有很多臺,一般在幾百臺到幾千臺,每臺伺服器配有數塊磁碟,整個叢集的儲存容量大概在幾PB~數百PB。
NameNode
- 負責客戶端請求的響應
- 負責元資料(檔案的名稱、副本系數、Block存放的DN)的管理
負責整個分散式檔案系統的元資料(MetaData)管理,即檔案路徑名、資料塊的ID以及儲存位置等資訊,類似os中的檔案分配表(FAT)。
HDFS為保證資料高可用,會將一個Block複製為多份(預設3份),並將多份相同的Block儲存在不同伺服器,甚至不同機架。當有磁碟損壞或某個DataNode伺服器宕機,甚至某個交換機宕機,導致其儲存的資料塊不能訪問時,客戶端會查詢其備份Block訪問。
3 S副本機制
HDFS中,一個檔案會被拆分為一個或多個數據塊。預設每個資料塊有三個副本,每個副本都存放在不同機器,而且每一個副本都有自己唯一的編號:
Block多份複製儲存的示意圖
檔案/users/sameerp/data/part-0的複製備份數設為2,儲存的BlockID分別為1、3:
- Block1的兩個備份儲存在DataNode0和DataNode2兩個伺服器上
- Block3的兩個備份儲存DataNode4和DataNode6兩個伺服器上
上述任一臺伺服器宕機後,每個資料塊都至少還有一個備份存在,不會影響對檔案/users/sameerp/data/part-0的訪問。
和RAID一樣,資料分成若干Block後,儲存到不同伺服器,實現資料大容量儲存,並且不同分片的資料能並行進行讀/寫操作,實現資料的高速訪問。
副本存放策略
副本存放:NameNode節點選擇一個DataNode節點去儲存block副本的過程,該過程的策略是在可靠性和讀寫頻寬間權衡。
《Hadoop權威指南》中的預設方式:
- 第一個副本會隨機選擇,但是不會選擇儲存過滿的節點
- 第二個副本放在和第一個副本不同且隨機選擇的機架
- 第三個和第二個放在同一機架上的不同節點
- 剩餘副本完全隨機節點
合理性分析
- 可靠性:block儲存在兩個機架
- 寫頻寬:寫操作僅穿過一個網路交換機
- 讀操作:選擇其中一個機架去讀
- block分佈在整個叢集
Google大資料“三駕馬車”的第一駕是GFS(Google 檔案系統),而Hadoop的第一個產品是HDFS,分散式檔案儲存是分散式計算的基礎。
這些年來,各種計算框架、各種演算法、各種應用場景不斷推陳出新,但大資料儲存的王者依然是HDFS。
4 HDFS的高可用設計
4.1 資料儲存故障容錯
磁碟介質在儲存過程中受環境或者老化影響,其儲存的資料可能會出現錯亂。
HDFS對儲存在DataNode上的資料塊,計算並存儲校驗和(CheckSum)。在讀資料時,重新計算讀取出來的資料的校驗和,校驗不正確就拋異常,應用程式捕獲異常後就到其他DataNode上讀取備份資料。
4.2 磁碟故障容錯
DataNode監測到本機的某塊磁碟損壞,就將該塊磁碟上儲存的所有BlockID報告給NameNode,NameNode檢查這些資料塊還在哪些DataNode上有備份,通知相應的DataNode伺服器將對應的資料塊複製到其他伺服器上,以保證資料塊的備份數滿足要求。
4.3 DataNode故障容錯
DataNode會通過心跳和NameNode保持通訊,如果DataNode超時未傳送心跳,NameNode就會認為這個DataNode已經宕機失效,立即查詢這個DataNode上儲存的資料塊有哪些,以及這些資料塊還儲存在哪些伺服器上,隨後通知這些伺服器再複製一份資料塊到其他伺服器上,保證HDFS儲存的資料塊備份數符合使用者設定的數目,即使再出現伺服器宕機,也不會丟失資料。
4.4 NameNode故障容錯
NameNode是整個HDFS的核心,記錄著HDFS檔案分配表資訊,所有的檔案路徑和資料塊儲存資訊都儲存在NameNode,如果NameNode故障,整個HDFS系統叢集都無法使用;如果NameNode上記錄的資料丟失,整個叢集所有DataNode儲存的資料也就沒用了。
所以,NameNode高可用容錯能力非常重要。NameNode採用主從熱備的方式提供高可用服務:
叢集部署兩臺NameNode伺服器:
- 一臺作為主伺服器提供服務
- 一臺作為從伺服器進行熱備
兩臺伺服器通過Zk選舉,主要是通過爭奪znode鎖資源,決定誰是主伺服器。而DataNode則會向兩個NameNode同時傳送心跳資料,但是隻有主NameNode才能向DataNode返回控制資訊。
正常執行期,主從NameNode之間通過一個共享儲存系統shared edits來同步檔案系統的元資料資訊。當主NameNode伺服器宕機,從NameNode會通過ZooKeeper升級成為主伺服器,並保證HDFS叢集的元資料資訊,也就是檔案分配表資訊完整一致。
軟體系統,效能差點,使用者也許可接受;使用體驗差,也許也能忍受。但若可用性差,經常出故障不可用,就麻煩了;如果出現重要資料丟失,那開發攤上大事。
而分散式系統可能出故障地方又非常多,記憶體、CPU、主機板、磁碟會損壞,伺服器會宕機,網路會中斷,機房會停電,所有這些都可能會引起軟體系統的不可用,甚至資料永久丟失。
所以在設計分散式系統的時候,軟體工程師一定要繃緊可用性這根弦,思考在各種可能的故障情況下,如何保證整個軟體系統依然是可用的。
5 保證系統可用性的策略
冗餘備份
任何程式、任何資料,都至少要有一個備份,也就是說程式至少要部署到兩臺伺服器,資料至少要備份到另一臺伺服器上。此外,稍有規模的網際網路企業都會建設多個數據中心,資料中心之間互相進行備份,使用者請求可能會被分發到任何一個數據中心,即所謂的異地多活,在遭遇地域性的重大故障和自然災害的時候,依然保證應用的高可用。
失效轉移
當要訪問的程式或者資料無法訪問時,需要將訪問請求轉移到備份的程式或者資料所在的伺服器上,這也就是失效轉移。失效轉移你應該注意的是失效的鑑定,像NameNode這樣主從伺服器管理同一份資料的場景,如果從伺服器錯誤地以為主伺服器宕機而接管叢集管理,會出現主從伺服器一起對DataNode傳送指令,進而導致叢集混亂,也就是所謂的“腦裂”。這也是這類場景選舉主伺服器時,引入ZooKeeper的原因。ZooKeeper的工作原理,我將會在後面專門分析。
降級
當大量的使用者請求或者資料處理請求到達的時候,由於計算資源有限,可能無法處理如此大量的請求,進而導致資源耗盡,系統崩潰。這種情況下,可以拒絕部分請求,即進行限流;也可以關閉部分功能,降低資源消耗,即進行降級。限流是網際網路應用的常備功能,因為超出負載能力的訪問流量在何時會突然到來,你根本無法預料,所以必須提前做好準備,當遇到突發高峰流量時,就可以立即啟動限流。而降級通常是為可預知的場景準備的,比如電商的“雙十一”促銷,為了保障促銷活動期間應用的核心功能能夠正常執行,比如下單功能,可以對系統進行降級處理,關閉部分非重要功能,比如商品評價功能。
總結
HDFS是如何通過大規模分散式伺服器叢集實現資料的大容量、高速、可靠儲存、訪問的。
1.檔案資料以資料塊的方式進行切分,資料塊可以儲存在叢集任意DataNode伺服器上,所以HDFS儲存的檔案可以非常大,一個檔案理論上可以佔據整個HDFS伺服器叢集上的所有磁碟,實現了大容量儲存。
2.HDFS一般的訪問模式是通過MapReduce程式在計算時讀取,MapReduce對輸入資料進行分片讀取,通常一個分片就是一個數據塊,每個資料塊分配一個計算程序,這樣就可以同時啟動很多程序對一個HDFS檔案的多個數據塊進行併發訪問,從而實現資料的高速訪問。關於MapReduce的具體處理過程,我們會在專欄後面詳細討論。
3.DataNode儲存的資料塊會進行復制,使每個資料塊在叢集裡有多個備份,保證了資料的可靠性,並通過一系列的故障容錯手段實現HDFS系統中主要元件的高可用,進而保證資料和整個系統的高可用。
- 帶你掌握 C 中三種類成員初始化方式
- 實踐GoF的設計模式:工廠方法模式
- DCM:一個能夠改善所有應用資料互動場景的中介軟體新秀
- 手繪圖解java類載入原理
- 關於加密通道規範,你真正用的是TLS,而非SSL
- 程式碼重構,真的只有複雜化一條路嗎?
- 解讀分散式排程平臺Airflow在華為雲MRS中的實踐
- 透過例項demo帶你認識gRPC
- 帶你聚焦GaussDB(DWS)儲存時遊標使用
- 傳統到敏捷的轉型中,誰更適合做Scrum Master?
- 輕鬆解決研發知識管理難題
- Java中觀察者模式與委託,還在傻傻分不清
- 如何使用Python實現影象融合及加法運算?
- 什麼是強化學習?
- 探索開源工作流引擎Azkaban在MRS中的實踐
- GaussDB(DWS) NOT IN優化技術解密:排他分析場景400倍效能提升
- Java中觀察者模式與委託,還在傻傻分不清
- Java中的執行緒到底有哪些安全策略
- 一圖詳解java-class類檔案原理
- Java中的執行緒到底有哪些安全策略