天天看點

HDFS的檔案寫入和讀取過程

一. 什麼是NameNode 、DataNode

1、 NameNode是一個中心伺服器,單一節點(簡化系統的設計和實作),負責管理檔案系統的名字空間(namespace)以及用戶端對檔案的通路

2、 檔案操作,namenode是負責檔案中繼資料的操作,datanode負責處理檔案内容的讀寫請求,跟檔案内容相關的資料流不經過Namenode,隻詢問它跟哪個dataNode聯系,否則NameNode會成為系統的瓶頸

3、 副本存放在哪些Datanode上由NameNode來控制,根據全局情況作出塊放置決定,讀取檔案時NameNode盡量讓使用者先讀取最近的副本,降低讀取網絡開銷和讀取延時

4、 NameNode全權管理資料庫的複制,它周期性的從叢集中的每個DataNode接收心跳信合和狀态報告,接收到心跳信号意味着DataNode節點工作正常,塊狀态報告包含了一個該DataNode上所有的資料清單

NameNode DataNode
存儲中繼資料 存儲檔案内容
中繼資料保持在記憶體中 檔案内容保持到磁盤
儲存檔案、block、DataNode之間的映射關系 維護了block id 到DataNode本地檔案的映射關系

二、HDFS寫入過程

HDFS的檔案寫入和讀取過程
HDFS的檔案寫入和讀取過程
詳細步驟解析:
1、 client發起檔案上傳請求,通過RPC與NameNode建立通訊,NameNode檢查目标檔案是否已存在,父目錄是否存在,傳回是否可以上傳;
2、 client請求第一個block該傳輸到哪些DataNode伺服器上;
3、 NameNode根據配置檔案中指定的備份數量及機架感覺原理進行檔案配置設定,傳回可用的DataNode的位址如:A,B,C;

注:Hadoop在設計時考慮到資料的安全與高效,資料檔案預設在HDFS上存放三份,存儲政策為本地一份,同機架内其它某一節點上一份,不同機架的某一節點上一份。
4、 client請求3台DataNode中的一台A上傳資料(本質上是一個RPC調用,建立pipeline),A收到請求會繼續調用B,然後B調用C,将整個pipeline建立完成,後逐級傳回client;
5、 client開始往A上傳第一個block(先從磁盤讀取資料放到一個本地記憶體緩存),以packet為機關(預設64K),A收到一個packet就會傳給B,B傳給C;A每傳一個packet會放入一個應答隊列等待應答。
6、 資料被分割成一個個packet資料包在pipeline上依次傳輸,在pipeline反方向上,逐個發送ack(指令正确應答),最終由pipeline中第一個DataNode節點A将pipelineack發送給client;
7、 當一個block傳輸完成之後,client再次請求NameNode上傳第二個block到伺服器。

           

或者

1)用戶端向namenode請求上傳檔案,namenode檢查目标檔案是否已存在,父目錄是否存在。
2)namenode傳回是否可以上傳。
3)用戶端請求第一個 block上傳到哪幾個datanode伺服器上。
4)namenode傳回3個datanode節點,分别為dn1、dn2、dn3。
5)用戶端請求dn1上傳資料,dn1收到請求會繼續調用dn2,然後dn2調用dn3,将這個通信管道建立完成。
6)dn1、dn2、dn3逐級應答用戶端
7)用戶端開始往dn1上傳第一個block(先從磁盤讀取資料放到一個本地記憶體緩存),以packet為機關,dn1收到一個packet就會傳給dn2,dn2傳給dn3;dn1每傳一個packet會放入一個應答隊列等待應答
8)當一個block傳輸完成之後,用戶端再次請求namenode上傳第二個block的伺服器。(重複執行3-7步)

           

三、HDFS讀取過程

HDFS的檔案寫入和讀取過程
HDFS的檔案寫入和讀取過程
詳細步驟解析
1、 Client向NameNode發起RPC請求,來确定請求檔案block所在的位置; 
2、 NameNode會視情況傳回檔案的部分或者全部block清單,對于每個block,NameNode 都會傳回含有該 block 副本的 DataNode 位址;  這些傳回的 DN 位址,會按照叢集拓撲結構得出 DataNode 與用戶端的距離,然後進行排序,排序兩個規則:網絡拓撲結構中距離 Client 近的排靠前;心跳機制中逾時彙報的 DN 狀态為 STALE,這樣的排靠後; 
3、 Client 選取排序靠前的 DataNode 來讀取 block,如果用戶端本身就是DataNode,那麼将從本地直接擷取資料(短路讀取特性); 
4、 底層上本質是建立 Socket Stream(FSDataInputStream),重複的調用父類 DataInputStream 的 read 方法,直到這個塊上的資料讀取完畢; 
5、 當讀完清單的 block 後,若檔案讀取還沒有結束,用戶端會繼續向NameNode 擷取下一批的 block 清單; 
6、 讀取完一個 block 都會進行 checksum 驗證,如果讀取 DataNode 時出現錯誤,用戶端會通知 NameNode,然後再從下一個擁有該 block 副本的DataNode 繼續讀。 
7、 read 方法是并行的讀取 block 資訊,不是一塊一塊的讀取;NameNode 隻是傳回Client請求包含塊的DataNode位址,并不是傳回請求塊的資料;
8、 最終讀取來所有的 block 會合并成一個完整的最終檔案。

           

或者

1)用戶端向namenode請求下載下傳檔案,namenode通過查詢中繼資料,找到檔案塊所在的datanode位址。
2)挑選一台datanode(就近原則,然後随機)伺服器,請求讀取資料。
3)datanode開始傳輸資料給用戶端(從磁盤裡面讀取資料放入流,以packet為機關來做校驗)。
4)用戶端以packet為機關接收,先在本地緩存,然後寫入目标檔案。

           

完!!

繼續閱讀