HDFS寫入和讀取流程
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
一、HDFS
HDFS全稱是Hadoop Distributed System。HDFS是為以流的方式存取大檔案而設計的。適用於幾百MB,GB以及TB,並寫一次讀多次的場合。而對於低延時資料訪問、大量小檔案、同時寫和任意的檔案修改,則並不是十分適合。
目前HDFS支援的使用介面除了Java的還有,Thrift、C、FUSE、WebDAV、HTTP等。HDFS是以block-sized chunk組織其檔案內容的,預設的block大小為64MB,對於不足64MB的檔案,其會佔用一個block,但實際上不用佔用實際硬碟上的64MB,這可以說是HDFS是在檔案系統之上架設的一箇中間層。之所以將預設的block大小設定為64MB這麼大,是因為block-sized對於檔案定位很有幫助,同時大檔案更使傳輸的時間遠大於檔案尋找的時間,這樣可以最大化地減少檔案定位的時間在整個檔案獲取總時間中的比例 。
二、HDFS的體系結構
構成HDFS主要是Namenode(master)和一系列的Datanode(workers)。Namenode是管理HDFS的目錄樹和相關的檔案元資料,這些資訊是以"namespace image"和"edit log"兩個檔案形式存放在本地磁碟,但是這些檔案是在HDFS每次重啟的時候重新構造出來的。Datanode則是存取檔案實際內容的節點,Datanodes會定時地將block的列表彙報給Namenode。
由於Namenode是元資料存放的節點,如果Namenode掛了那麼HDFS就沒法正常執行,因此一般使用將元資料持久儲存在本地或遠端的機器上,或者使用secondary namenode來定期同步Namenode的元資料資訊,secondary namenode有點類似於MySQL的Master/Salves中的Slave,"edit log"就類似"bin log"。如果Namenode出現了故障,一般會將原Namenode中持久化的元資料拷貝到secondary namenode中,使secondary namenode作為新的Namenode執行起來。
三、讀寫流程
GFS論文提到的檔案讀取簡單流程:
詳細流程:
檔案讀取的過程如下:
- 使用HDFS提供的客戶端開發庫Client,向遠端的Namenode發起RPC請求;
- Namenode會視情況返回檔案的部分或者全部block列表,對於每個block,Namenode都會返回有該block拷貝的DataNode地址;
- 客戶端開發庫Client會選取離客戶端最接近的DataNode來讀取block;如果客戶端本身就是DataNode,那麼將從本地直接獲取資料.
- 讀取完當前block的資料後,關閉與當前的DataNode連線,併為讀取下一個block尋找最佳的DataNode;
- 當讀完列表的block後,且檔案讀取還沒有結束,客戶端開發庫會繼續向Namenode獲取下一批的block列表。
- 讀取完一個block都會進行checksum驗證,如果讀取datanode時出現錯誤,客戶端會通知Namenode,然後再從下一個擁有該block拷貝的datanode繼續讀。
GFS論文提到的寫入檔案簡單流程:
詳細流程:
寫入檔案的過程比讀取較為複雜:
- 使用HDFS提供的客戶端開發庫Client,向遠端的Namenode發起RPC請求;
- Namenode會檢查要建立的檔案是否已經存在,建立者是否有許可權進行操作,成功則會為檔案建立一個記錄,否則會讓客戶端丟擲異常;
- 當客戶端開始寫入檔案的時候,開發庫會將檔案切分成多個packets,並在內部以資料佇列"data queue"的形式管理這些packets,並向Namenode申請新的blocks,獲取用來儲存replicas的合適的datanodes列表,列表的大小根據在Namenode中對replication的設定而定。
- 開始以pipeline(管道)的形式將packet寫入所有的replicas中。開發庫把packet以流的方式寫入第一個datanode,該datanode把該packet儲存之後,再將其傳遞給在此pipeline中的下一個datanode,直到最後一個datanode,這種寫資料的方式呈流水線的形式。
- 最後一個datanode成功儲存之後會返回一個ack packet,在pipeline裡傳遞至客戶端,在客戶端的開發庫內部維護著"ack queue",成功收到datanode返回的ack packet後會從"ack queue"移除相應的packet。
- 如果傳輸過程中,有某個datanode出現了故障,那麼當前的pipeline會被關閉,出現故障的datanode會從當前的pipeline中移除,剩餘的block會繼續剩下的datanode中繼續以pipeline的形式傳輸,同時Namenode會分配一個新的datanode,保持replicas設定的數量。