hadoop之hdfs架構詳解

HDFS介紹

HDFS(Hadoop Distributed File System,Hadoop分佈式文件系統),它是一個高度容錯性的系統,適合部署在廉價的機器上。HDFS能提供高吞吐量的數據訪問,適合那些有著超大數據集(large data set)的應用程序。 

HDFS優勢

1、可構建在廉價機器上,設備成本相對低
2、高容錯性,HDFS將數據自動保存多個副本,副本丟失後,自動恢復,防止數據丟失或損壞
3、適合批處理,HDFS適合一次寫入、多次查詢(讀取)的情況,適合在已有的數據進行多次分析,穩定性好
4、適合存儲大文件,其中的大表示可以存儲單個大文件,因為是分塊存儲,以及表示存儲大量的數據

HDFS劣勢

1、由於提高吞吐量,降低實時性
2、由於每個文件都會在namenode中記錄元數據,如果存儲了大量的小文件,會對namenode造成很大的壓力
3、不合適小文件處理,在mapreduce的過程中小文件的數量會造成map數量的增大,導致資源被佔用,而且速度慢。
4、不適合文件的修改,文件只能追加在文件的末尾,不支持任意位置修改,不支持多個寫入者操作

HDFS架構

hadoop之hdfs架構詳解


NameNode:管理文件系統命名空間的主服務器和管理客戶端對文件的訪問組成,如打開,關閉和重命名文件和目錄。負責管理文件目錄、文件和block的對應關係以及block和datanode的對應關係,維護目錄樹,接管用戶的請求

DataNode:管理連接到它們運行的​​節點的存儲,負責處理來自文件系統客戶端的讀寫請求。DataNodes還執行塊創建,刪除

Client:(客戶端)代表用戶通過與nameNode和datanode交互來訪問整個文件系統,HDFS對外開放文件命名空間並允許用戶數據以文件形式存儲。用戶通過客戶端(Client)與HDFS進行通訊交互。

HDFS讀數據流程

hadoop之hdfs架構詳解

1、客戶端通過FileSystem對象(DistributedFileSystem)的open()方法來打開希望讀取的文件。

2、DistributedFileSystem通過遠程調用(RPC)來調用namenode,獲取到每個文件的起止位置。對於每一個塊,namenode返回該塊副本的datanode。這些datanode會根據它們與客戶端的距離(集群的網絡拓撲結構)排序,如果客戶端本身就是其中的一個datanode,那麼就會在該datanode上讀取數據。DistributedFileSystem遠程調用後返回一個FSDataInputStream(支持文件定位的輸入流)對象給客戶端以便於讀取數據,然後FSDataInputStream封裝一個DFSInputStream對象。該對象管理datanode和namenode的IO。

3、客戶端對這個輸入流調用read()方法,存儲著文件起始幾個塊的datanode地址的DFSInputStream隨即連接距離最近的文件中第一個塊所在的datanode,通過數據流反覆調用read()方法,可以將數據從datanode傳送到客戶端。當讀完這個塊時,DFSInputStream關閉與該datanode的連接,然後尋址下一個位置最佳的datanode。

客戶端從流中讀取數據時,塊是按照打開DFSInputStream與datanode新建連接的順序讀取的。它也需要詢問namenode來檢索下一批所需塊的datanode的位置。一旦客戶端完成讀取,就對FSDataInputStream調用close()方法。

注意:在讀取數據的時候,如果DFSInputStream在與datanode通訊時遇到錯誤,它便會嘗試從這個塊的另外一個臨近datanode讀取數據。他也會記住那個故障datanode,以保證以後不會反覆讀取該節點上後續的塊。DFSInputStream也會通過校驗和確認從datanode發送來的數據是否完整。如果發現一個損壞的塊, DFSInputStream就會在試圖從其他datanode讀取一個塊的複本之前通知namenode。


總結:在這個設計中,namenode會告知客戶端每個塊中最佳的datanode,並讓客戶端直接聯繫該datanode且檢索數據。由於數據流分散在該集群中的所有datanode,所以這種設計會使HDFS可擴展到大量的併發客戶端。同時,namenode僅需要響應位置的請求(這些信息存儲在內存中,非常高效),而無需響應數據請求,否則隨著客戶端數量的增長,namenode很快會成為一個瓶頸。

HDFS寫數據流程

hadoop之hdfs架構詳解

1、首先客戶端通過DistributedFileSystem上的create()方法指明一個預創建的文件的文件名

2、DistributedFileSystem再通過RPC調用向NameNode申請創建一個新文件(這時該文件還沒有分配相應的block)。namenode檢查是否有同名文件存在以及用戶是否有相應的創建權限,如果檢查通過,namenode會為該文件創建一個新的記錄,否則的話文件創建失敗,客戶端得到一個IOException異常。DistributedFileSystem返回一個FSDataOutputStream以供客戶端寫入數據,與FSDataInputStream類似,FSDataOutputStream封裝了一個DFSOutputStream用於處理namenode與datanode之間的通信。

3、當客戶端開始寫數據時(,DFSOutputStream把寫入的數據分成包(packet), 放入一箇中間隊列——數據隊列(data queue)中去。DataStreamer從數據隊列中取數據,同時向namenode申請一個新的block來存放它已經取得的數據。namenode選擇一系列合適的datanode(個數由文件的replica數決定)構成一個管道線(pipeline),這裡我們假設replica為3,所以管道線中就有三個datanode。

4、DataSteamer把數據流式的寫入到管道線中的第一個datanode中,第一個datanode再把接收到的數據轉到第二個datanode中,以此類推。

5、DFSOutputStream同時也維護著另一箇中間隊列——確認隊列(ack queue),確認隊列中的包只有在得到管道線中所有的datanode的確認以後才會被移出確認隊列

如果某個datanode在寫數據的時候當掉了,下面這些對用戶透明的步驟會被執行:


管道線關閉,所有確認隊列上的數據會被挪到數據隊列的首部重新發送,這樣可以確保管道線中當掉的datanode下流的datanode不會因為當掉的datanode而丟失數據包。

在還在正常運行的datanode上的當前block上做一個標誌,這樣噹噹掉的datanode重新啟動以後namenode就會知道該datanode上哪個block是剛才當機時殘留下的局部損壞block,從而可以把它刪掉。

已經當掉的datanode從管道線中被移除,未寫完的block的其他數據繼續被寫入到其他兩個還在正常運行的datanode中去,namenode知道這個block還處在under-replicated狀態(也即備份數不足的狀態)下,然後他會安排一個新的replica從而達到要求的備份數,後續的block寫入方法同前面正常時候一樣。有可能管道線中的多個datanode當掉(雖然不太經常發生),但只要dfs.replication.min(默認為1)個replica被創建,我們就認為該創建成功了。剩餘的replica會在以後異步創建以達到指定的replica數。

6、當客戶端完成寫數據後,它會調用close()方法。這個操作會沖洗(flush)所有剩下的package到pipeline中。

7、等待這些package確認成功,然後通知namenode寫入文件成功。這時候namenode就知道該文件由哪些block組成(因為DataStreamer向namenode請求分配新block,namenode當然會知道它分配過哪些blcok給給定文件),它會等待最少的replica數被創建,然後成功返回。


注意:hdfs在寫入的過程中,有一點與hdfs讀取的時候非常相似,就是:DataStreamer在寫入數據的時候,每寫完一個datanode的數據塊,都會重新向nameNode申請合適的datanode列表。這是為了保證系統中datanode數據存儲的均衡性。

hdfs寫入過程中,datanode管線的確認應答包並不是每寫完一個datanode,就返回一個確認應答,而是一直寫入,直到最後一個datanode寫入完畢後,統一返回應答包。如果中間的一個datanode出現故障,那麼返回的應答就是前面完好的datanode確認應答,和故障datanode的故障異常。這樣我們也就可以理解,在寫入數據的過程中,為什麼數據包的校驗是在最後一個datanode完成。


分享到:


相關文章: