Hadoop之HDFS
HDFS即Hadoop Distributed File System分布式文件系統,它的設計目標是把超大數據集存儲到分布在網絡中的多臺普通商用計算機上,並且能夠提供高可靠性和高吞吐量的服務。分布式文件系統要比普通磁盤文件系統復雜,因為它要引入網絡編程,分布式文件系統要容忍節點故障也是一個很大的挑戰。
Namenode 和 Datanode HDFS采用master/slave架構。一個HDFS集群是一個Namenode和一定數量的Datanode組成。Namenode是一個中心服務器,負責管理文件系統的namespace和客戶端對文件的訪問。Datenode在集群中一般是一個節點一個,負責管理節點上他們附帶的存儲。在內部,一個文件其實分成一個或多個block,這些block存儲在Datanode集合裏。Namenode執行文件系統的namespace操作,例如打開、關閉、重命名文件和目錄,同時決定block到具體Datanode節點的映射。Datanode在Namenode的指揮下進行block的創建、刪除和復制。Namenode和Datenode都是設計成可以跑在普通的廉價的運行linux的機器上。HDFS采用java語言開發,因此可以部署在很大範圍的機器上。一個典型的部署場景是一臺機器跑一個單獨的Namenode節點,集群中的其他機器各跑一個Datanode實例。這個架構並不排除一臺機器上跑多個Datanode,不過這比較少見。 單個節點的Namenode大大簡化了系統的架構。Namenode負責保管和管理所有的HDFS元數據,因而用戶數據就不需要通過Namenode(也就是說文件數據的讀寫是直接在Datanode上)。 文件系統的namespace1、客戶端調用FileSystem實例的open方法,獲得這個文件對應的輸入流InputStream。
2、通過RPC遠程調用NameNode,獲得NameNode中此文件對應的數據塊保存位置,包括這個文件的副本的保存位置(主要是各DataNode的地址)
3、獲得輸入流之後,客戶端調用read方法讀取數據。選擇最近的DataNode建立連接並讀取數據。
4、如果客戶端和其中一個DataNode位於同一機器(比如MapReduce)過程中的mapper 和 reducer ),那麽就會直接從本地讀取數據。
5、到達數據塊末端,關閉與這個DataNode的連接,然後重新查找下一個數據塊。
6、不斷執行第2-5步直到數據全部讀完。
7、客戶端調用close,關閉輸入流DF S InputStream。
數據寫策略
1、客戶端調用FileSystem實例的create方法,創建文件。NameNode通過一些檢查,比如文件是否存在,客戶端是否擁有創建權限等;通過檢查之後,在NameNode添加文件信息。註意,因為此時文件沒有數據,所以NameNode上也沒有文件數據塊的信息。
2、創建結束之後,HDFS會返回一個輸出流,DFSDataOutputStream給客戶端。
3、客戶端調用輸出流DFSDataOutPutStream的write方法向HDFS中對應的文件寫入數據。
4、數據首先會被分包,這些分包會寫入一個輸出流的內部隊列Data隊列中,接收完數據分包,輸出流DFSDataOutputStream會向NameNode申請保存文件和副本數據塊的若幹個DataNode,這若幹個DataNode會形成一個數據傳輸管道。DFSDataOutputStream將數據傳輸給距離上最短的DataNode,這個DataNode接收到數據包之後會傳給下一個DataNode。數據在各DataNode之間通過管道流動,而不是全部由輸出流分發,以減少傳輸開銷。
5、因為各DataNode位於不同機器上,數據需要通過網絡發送,所以,為了保證所有DataNode的數據都是準確的,接受到數據的DataNode要向發送者發送ACK。對於某個數據塊,只有當DFSDataOutputStream收到了所有DataNode的ACK,才能確認傳輸結束。DFSDataOutputStream內部專門維護了一個等待ACK隊列,這個隊列保存已經進入管道傳輸數據、但是並未被完全確認的數據包。
6、不斷執行3-5步直到數據全部寫完,客戶端調用close關閉文件。
7、DFSDataInputStream繼續等待直到所有數據寫入完畢並被確認,調用complete方法通知NameNode文件寫入完成。NameNode接受到complete消息之後,等待相應數量的副本寫入完畢後,告知客戶端。
Hadoop之HDFS