從HDFS的寫入和讀取中,我發現了點東西

華為雲開發者社群發表於2022-03-25
摘要:從HDFS的寫入和讀取中,我們能學習到什麼?

本文分享自華為雲社群《從HDFS的寫入和讀取中,我們能學習到什麼》,作者: breakDawn 。

最近開發過程涉及了一些和檔案讀取有關的問題,於是對hdfs的讀取機制感到興趣,順便深入學習了一下。

寫入

  1. 客戶端向NameNode發出寫檔案請求,告訴需要寫的檔名和路徑、使用者
  2. NameNode檢查是否已存在檔案、檢查許可權。如果通過,會返回一個輸出流物件
  • 注意此時會按照“日誌先行“原則,寫入NameNode的editLog
  1. 客戶端按照128MB的大小切分檔案。 也就是block大小
  2. 客戶端把nameNode傳來的DataNode列表和Data資料一同傳送給 最近的第一個DataNode節點。
  3. 第一個dataNode節點收到資料和DataNode列表時, 會先根據列表,找到下一個自己要連線的最近DataNode, 刪除自己後,再一樣往下發。以此類推,發完3臺或者N臺。
  • 傳輸單位是packet,包,比block小一點。
  1. dataNode每寫完一個block塊, 則返回ACK資訊給上一個節點進行確認。(注意是寫完block才確認)
  2. 寫完資料, 關閉輸出流, 傳送完成資訊給DataNode

寫過程的核心總結:

  • 客戶端只向一個dataNode寫資料,然後下一個dataNode接著往另一個dataNode寫,串聯起來。
  • 按128MB分block。 每次傳資料按pack傳。 校驗按照chunk 校驗,每次chunk都會寫入pack。
  • 寫完block才發ACK確認。

Q: NameNode的editlog有什麼用?怎麼起作用的?
A:作用:

  • 硬碟中需要有一份後設資料的映象——FSImage
  • 每次要修改後設資料就資訊時,必須得改檔案(hdfs沒有資料庫)
  • 可能會比較久,改的時候如果斷電了,就丟失這個操作了

為了避免丟失,引入editlog,每次修改後設資料前,先追加方式寫入editlog, 然後再處理,這樣即使斷電了也能修復。

一般都是那些更改操作有斷開風險,為了確保能恢復,都會引入這類操作。

Q: 什麼時候傳送完成訊號? 全部節點都寫入完成嗎
A:傳送完成訊號的時機取決於叢集是強一致性還是最終一致性,強一致性則需要所有DataNode寫完後才向NameNode彙報。最終一致性則其中任意一個DataNode寫完後就能單獨向NameNode彙報,HDFS一般情況下都是強調強一致性

Q: 怎麼驗證寫入時的資料完整性?
A:

  • 因為每個chunk中都有一個校驗位,一個個chunk構成packet,一個個packet最終形成block,故可在block上求校驗和。
  • 當客戶端建立一個新的HDFS檔案時候,分塊後會計算這個檔案每個資料塊的校驗和,此校驗和會以一個隱藏檔案形式儲存在同一個 HDFS 名稱空間下。就是.meta檔案

從HDFS的寫入和讀取中,我發現了點東西

  • 當client端從HDFS中讀取檔案內容後,它會檢查分塊時候計算出的校驗和(隱藏檔案裡)和讀取到的檔案塊中校驗和是否匹配,如果不匹配,客戶端可以選擇從其他 Datanode 獲取該資料塊的副本。

Q: 寫入時怎麼確定最近節點?
A:按照按照hadoop時設定的機架、資料中心、節點來估算

假設有資料中心d1機架r1中的節點n1。該節點可以表示為/d1/r1/n1。利用這種標記,這裡給出四種距離描述。

  • Distance(/d1/r1/n1, /d1/r1/n1)=0(同一節點上的程式)
  • Distance(/d1/r1/n1, /d1/r1/n2)=2(同一機架上的不同節點)
  • Distance(/d1/r1/n1, /d1/r3/n2)=4(同一資料中心不同機架上的節點)
  • Distance(/d1/r1/n1, /d2/r4/n2)=6(不同資料中心的節點)

讀取

讀取就比較簡單了,沒有那種複雜的序列過程。NameNode直接告訴客戶端去哪讀就行了。

  1. client訪問NameNode,查詢後設資料資訊,獲得這個檔案的資料塊位置列表,返回輸入流物件。
  2. 就近挑選一臺datanode伺服器,請求建立輸入流 。
  3. DataNode向輸入流中中寫資料,以packet為單位來校驗。
  4. 關閉輸入流

 

點選關注,第一時間瞭解華為雲新鮮技術~

相關文章