HDFS的增刪改查概述


              HDFS的數據流之增刪改查概述

                                        作者:尹正傑

版權聲明:原創作品,謝絕轉載!否則將追究法律責任。

 

 

 

一.HDFS上傳(寫入/增)流程

  

  如上圖所示,HDFS在做寫入文件時流程大概如下所示:
    1>.客戶端通過Distributed FileSystem模塊向NameNode請求上傳文件,NameNode需要驗證客戶端是否有權限寫入,還需要檢查目標文件是否已存在,如果是多級目錄還需要檢查父目錄是否存在;

    2>.NameNode返回是否可以上傳,如果不可以上傳(比如沒權限或目標文件已經存在),則寫入流程到此終止,如果有權限上傳,則需要繼續執行下面的流程;

    3>.客戶端此時會開啟一個輸出流(FSDataOutputStream),於此同時會發起請求上傳第一個Block(這個塊大小默認是128MB);

    4>.NameNode接收到請求后會像客戶端返回可以存儲數據的DataNode列表,這個DataNode列表的主機數量取決於你設置的集群副本數,若你設置的是默認副本數3個,則會返回三個DataNode主機,比如:["hadoop102.yinzhengjie.org.cn","hadoop103.yinzhengjie.org.cn","hadoop104.yinzhengjie.org.cn"];
    
    5>.客戶端通過輸出流(FSDataOutputStream)向最近的一個DataNode節點(比如:"hadoop102.yinzhengjie.org.cn")發起請求建立通道,該節點並不會立即響應客戶端,而是會向"hadoop103.yinzhengjie.org.cn"節點發起建立通道的請求,"hadoop103.yinzhengjie.org.cn"接收到"hadoop102.yinzhengjie.org.cn"發來的建立通道請求也不會立即回復,而會向"hadoop104.yinzhengjie.org.cn"發起建立通道請求;
    
    6>."hadoop104.yinzhengjie.org.cn"收到"hadoop103.yinzhengjie.org.cn"發來的請求建立通道時,在正常的情況下,"hadoop104.yinzhengjie.org.cn"會應答"hadoop103.yinzhengjie.org.cn"節點建立通道成功,此時"hadoop103.yinzhengjie.org.cn"收到"hadoop104.yinzhengjie.org.cn"的應答成功消息后會立即響應"hadoop102.yinzhengjie.org.cn"應答成功,最終"hadoop102.yinzhengjie.org.cn"會響應客戶端應答成功。這意味着這個"串連"的通道被打通啦;
    
    7>.通道建立成功后,客戶端開始往最近的DataNode(比如"hadoop102.yinzhengjie.org.cn")傳輸Packet(64Kb),"hadoop102.yinzhengjie.org.cn"收到Packet數據是在內存中的,此時它會將內存的數據一邊落地,一邊將數據發給和"hadoop103.yinzhengjie.org.cn"節點建立的通道,當"hadoop103.yinzhengjie.org.cn"節點收到"hadoop102.yinzhengjie.org.cn"的Packet時,也會一邊將數據進行落地,一邊將數據發給和"hadoop104.yinzhengjie.org.cn"節點建立的通道。當"hadoop104.yinzhengjie.org.cn"將"hadoop103.yinzhengjie.org.cn"發來的Packet落地后,會返回消息給"hadoop103.yinzhengjie.org.cn"數據寫入成功的消息,此時"hadoop103.yinzhengjie.org.cn"接收到"hadoop104.yinzhengjie.org.cn"的數據寫入成功的消息后,它還需要等待自己的Packet數據落地成功后,才會將數據落地成功的消息返回給"hadoop102.yinzhengjie.org.cn",同理,當"hadoop102.yinzhengjie.org.cn"收到了"hadoop103.yinzhengjie.org.cn"的消息落地成功后,他也需要將自己的Packet落地成功后參會返回給客戶端說它也落地成功。需要注意的是:發送Packet並不是等待所有節點的第一個Packet完全落地以后才會發送第二個Packet,而是將一個塊大小拆分成多個Packet以一個隊列的形式發送的喲,也就是說每個主機上都維護了一個Packet隊列;
    
    8>.當一個Block傳輸完成之后,客戶端再次請求NameNode上傳第二個Block的服務器,過程就是重復上述步驟。當所有的塊傳輸完畢后,客戶端會告訴NameNode數據傳輸完畢,與此同時會關閉掉輸出流(FSDataOutputStream)以釋放本地資源,NameNode收到客戶端數據傳輸完畢的消息后,會添加響應的元數據信息;
  
  常見問題刨析:
    Q1:DFSOutputStream是基於什么為單位上傳數據的呢?
      答:DFSOutputStream會將文件分割成packets數據包,然后將這些packets寫到其內部的一個叫做data queue(數據隊列)。

    Q2:如果建立管道失敗意味着什么呢?       答:意味着客戶端寫入DataNode數據失敗了,此時客戶端應該會拋出一個異常有關於和DataNode節點建立連接失敗的相關信息。
    Q3:如果上傳數據在和第一個數據節點(DataNode)傳輸數據失敗意味着什么呢?       答:意味着數據傳輸失敗了。
    Q4:如果上傳數據在和第一個數據節點(DataNode)是正常的,但是在第二個或者第三個數據節點傳輸數據失敗意味着什么呢
?       答:如果第一個節點數據寫入是正常的,默認情況下,別說后面的兩個節點有任意一個掛掉,就算后面的所有DataNode節點同時掛掉,本次寫入數據依舊是成功后,只不過此時該數據塊只有一個副本,在做心跳信息匯報時NameNode會重新選取2個節點來將該節點的數據同步到其它的兩個節點上喲。當然這個功能依賴於dfs.replication.min(默認為1,Hadoop2.9.2版本已經將其更名為dfs.namenode.replication.min)參數,如果你將dfs.namenode.replication.min的數字改為2,那也就意味着如果有三個節點上傳數據,你必須得保證前兩個數據是寫入成功的喲,這個參數我不建議設置過大,設置過大的確可以提升可靠性,但這也降低了可用性。
    Q5:每次上傳一個新的Block都會創建一個新的輸出流(FSDataOutputStream)嗎
?       答:並不會,在整個上傳過程中只有一個輸出流(FSDataOutputStream)喲。

    Q6:數據被切割成不同的塊上傳到服務器上,那么問題來了,這個Block到底時NameNode切割的還是DataNode切割的呢?
      答:切割塊(Block)是客戶端完成的操作。      

 

二.HDFS下載(讀取/查)流程

  如上圖所示,HDFS的讀取流程大致如下:
    1>.客戶端通過Distributed FileSystem(集群的抽象封裝)向NameNode請求下載文件;

    2>.NameNode通過查詢元數據(包括文件所在路徑及其權限信息),如果文件不存在直接返回客戶端文件不存在,如果文件存在則根據元數據信息判斷用戶是否有權限讀取,如果無權限訪問則到此步驟結束,如果有權限訪問可以繼續下面的步驟;

    3>.客戶端創建一個輸入流(FSDataInputStream)並請求下載第一個Block(塊大小默認是128MB);

    4>.NameNode返回DataNode的列表;

    5>.就近原則挑選一台DataNode服務器(比如"hadoop102.yinzhengjie.org.cn"),請求與這一台DataNode主機建立通道即可;

    6>."hadoop102.yinzhengjie.org.cn"主機應答成功后,就開始傳輸Package給客戶端的輸入流(FSDataInputStream),最后客戶端落地到本地磁盤;

    7>.當一個Block傳輸完成之后,客戶端再次請求NameNode下載第二個Block的服務器,過程就是重復上述步驟

    8>.當所有的塊傳輸完畢后,客戶端會告訴NameNode數據傳輸完畢,與此同時會關閉掉輸出流(FSDataOutputStream)以釋放本地資源,NameNode收到客戶端數據傳輸完畢的消息后,會添加響應的元數據信息。   常見問題刨析: Q1:在下載文件時,客戶端還需要和返回的DataNode列表的所有主機建立通道嗎
? 答:不需要,它只需要和最近一台DataNode主機建立通道完成數據傳輸即可,如果最近一台DataNode建立通信失敗則會隨機挑選DataNode列表的主機進行數據傳輸,如果在此時所有的DataNode均不可訪問這意味文件下載失敗。 Q2:返回DataNode的列表個數和什么有關? 答:這個DataNode列表的主機數量取決於你設置的集群副本數,若你設置的是默認副本數是3個,則會返回三個DataNode主機,比如:["hadoop102.yinzhengjie.org.cn","hadoop103.yinzhengjie.org.cn","hadoop104.yinzhengjie.org.cn"]; Q3:DataNode主機列表的在讀取數據時僅有一台會讀取,那么其它的DataNode都空閑着,它們的作用是什么呢? 答:其實就是一個備胎的作用,當一個節點由於某種不可描述的原因意外宕機時,此時可以從DataNode列表的其它主機隨機選擇一個主機也能下載數據。

 

三.HDFS的刪除流程

  我們上面分析了HDFS的上傳和下載流程。我們發現無論是上傳還是下載文件都得客戶端來參與整個過程。

  那么問題來啦,刪除文件的工作流程是如何的呢?
    答:刪除文件過程並不需要客戶端來參與整個過程,它只需要告訴NameNode要刪除哪個元數據信息即可,NameNode和DataNode之間有心跳信息,當NameNode和DataNode進行相互通信時,NameNode知道哪些節點真正存儲元數據信息的數據,它會將刪除指令伴隨NameNode的心跳信息發送給相應的DataNode刪除數據。
  

 

四.HDFS的修改流程

  首先我們要明確一點,HDFS僅支持數據追加(append),不支持文件的隨機修改。

  如果你需要修改的是元數據信息,這個問題倒是不大,因為元數據信息的修改只是在NameNode節點完成,但是如果你想要隨機修改HDFS的數據是不允許的。

  我們在Hue組件中給我們一種錯覺,好像編輯文件后就能修改似的,但實際上Hue幫我們修改數據前,是先將之前的版本數據刪除掉在將新的文件內容上傳上去。如果你修改的文件內容比較大,這意味着這個時間會很長。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM