HDFS的讀寫流程

小钱没有钱發表於2024-11-03

HDFS的讀寫流程

寫資料

1、宏觀

hdfs寫資料宏觀流程

1、客戶端發起請求到NameNode,呼叫Hadoop中的一個類叫做DistributedFileSystem建立物件,再利用這個物件透過RPC通訊協議呼叫NameNode去建立一個沒有blocks關聯的新檔案。在建立之前NameNode會做各種校驗:比如該檔案是否存在,客戶端有無許可權去建立...如果校驗透過,NameNode就會記錄下新檔案,否則傳出IO異常。

2、 如果校驗成功,那就會返回給客戶端一個FSDataOutoutStream物件(相當於輸出流),客戶端可以利用這個物件去寫資料。客戶端開始對檔案進行切分,切分成一個個block塊。

3、客戶端寫資料之前要想NameNode詢問這個新些block最適合儲存的在哪幾個datanode裡,要向那個節點上寫入資料。假設所建立的檔案叫a.txt,在NameNode校驗成功後,會進行一系列分析生成a.txt的檔案資訊(副本資訊與存放節點的資訊)。而且在NameNode分析計算出來哪幾個節點適合去儲存這個新檔案及其副本,在這幾個節點之間會生成一個通道pipeline.DataStreamer【pipeline.DataStreamer是透過資料流來處理的,DataStreamer是Hadoop中的一個類,用於接受資料佇列data queue】

4、客戶端從NameNode得到資訊後會將資料打包成一個個packet,一個block塊中有2048個packet,一個packet的大小為64kb。客戶端會透過機架感知獲取最近的子節點建立連線通道。客戶端利用NameNode的FSDataOutoutStream將packet傳送到第一個子節點上。然後在第一個子節點中,然後根據副本資訊將packet透過各個子節點之間的pipeline通道傳送到各個子節點上去(由NameNode分析計算得出的節點),當傳送到最後一個子節點時,子節點會方向沿著pipeline通道傳送一個ack值一直到第一個子節點,最後將這個ack值傳送給客戶端,客戶端以ack值來判斷來各個節點已經收到了第一個packet。由此客戶端開始已同樣的方法傳送第二個packet,以此類推。

5、當檔案中最後一個block塊中 最後一個package返回的ack值到達客戶端,客戶端關FSDataOutoutStream流,子節點之間的pipeline通道斷開,HDFS寫資料完畢

宏觀寫資料角度引出的思考:

package在傳輸過程中,若突然斷電或其他異常導致傳輸中斷,有可能會導致資料丟失
客戶端怎麼知道當前的ack確認值表示的是最後一個package

2、微觀

hdfs寫資料微觀角度

1、當客戶端要上傳一個檔案時,要先將檔案切分為一個個block塊,一個block塊又分為一個個packet。然後透過FSDataOutoutStream將一個個packet傳送到最近的子節點上。

2、一個package由兩大部分構成,packet header和packet data。package hearder中有有pkt Len,offset In Pkt,SeqNo,Last Packet In Block,Data Len。Last Packet In Block就是儲存是不是最後一個packet的資訊true或者false。packetdata又分為ChunkData和Chunk Check sum,每個Check sum是負責校驗每個Data是否完整的。

3、當拿到第一個packet時,將packet放入資料佇列data queue中,後續的packet依次放入佇列中,除了資料佇列還有一個確認佇列ack queue,當packet要透過FSDataOutoutStream傳輸給各個子節點之前,客戶端會在資料佇列中複製一份給確認佇列然後再傳送給第一個子節點,第一個子節點再根據副本資訊複製給第二個子節點,第二個再複製給第三個,節點之間是透過pipeline通道進行資料傳輸,當packet到達最後一個子節點時,最後一個子節點再複製一份packet命名為ack值反向沿著pipeline通道傳輸給客戶端。實際上是傳輸到客戶端中的確認佇列,當確認佇列收到ackt值時將原本的複製的packet刪除,至此第一個packet傳輸完畢。

4、當packet在傳輸過程中發生異常無法正常傳輸時,客戶端中的確認佇列沒有收到ack值,然後客戶端就會認為在傳輸過程中出現了異常,然後各個節點刪除該packet最後再重新傳輸。

相關文章