HDFS的讀寫流程


一、簡介

  HDFS(Hadoop Distributed File System)是GFS的開源實現。

1.優點:

  能夠運行在廉價機器上,硬件出錯常態,需要具備高容錯性
  流式數據訪問,而不是隨機讀寫
  面向大規模數據集,能夠進行批處理、能夠橫向擴展
  簡單一致性模型,假定文件是一次寫入、多次讀取

2.缺點:

  不支持低延遲數據訪問
  不適合大量小文件存儲(因為每條元數據占用空間是一定的)
  不支持並發寫入,一個文件只能有一個寫入者
  不支持文件隨機修改,僅支持追加寫入

3.數據單位:

  block :文件上傳前需要分塊,這個塊就是block,一般為128MB,可以修改。因為塊太小:尋址時間占比過高。塊太大:Map任務數太少,作業執行速度變慢。它是最大的

      一個單位。

  packet :packet是第二大的單位,它是client端向DataNode,或DataNode的PipLine之間傳數據的基本單位,默認64KB。

  chunk :chunk是最小的單位,它是client向DataNode,或DataNode的PipLine之間進行數據校驗的基本單位,默認512Byte,因為用作校驗,故每個chunk需要帶有4Byte

      的校驗位。所以實際每個chunk寫入packet的大小為516Byte。由此可見真實數據與校驗值數據的比值 約為128 : 1。(即64*1024 / 512)

二、HDFS讀流程

 

讀詳細步驟:

  1、client訪問NameNode,查詢元數據信息,獲得這個文件的數據塊位置列表,返回輸入流對象。
  2、就近挑選一台datanode服務器,請求建立輸入流 。
  3、DataNode向輸入流中中寫數據,以packet為單位來校驗。
  4、關閉輸入流

三、HDFS寫流程

寫詳細步驟:

  1、客戶端向NameNode發出寫文件請求。

  2、檢查是否已存在文件、檢查權限。若通過檢查,直接先將操作寫入EditLog,並返回輸出流對象。

    (注:WAL,write ahead log,先寫Log,再寫內存,因為EditLog記錄的是最新的HDFS客戶端執行所有的寫操作。如果后續真實寫操作失敗了,

    由於在真實寫操作之前,操作就被寫入EditLog中了,故EditLog中仍會有記錄)

  3、client端按128MB的塊切分文件。

  4、client將NameNode返回的DataNode列表和Data數據一同發送給最近的第一個DataNode節點,此后client端和多個DataNode構成pipeline管道。

    client向第一個DataNode寫入一個packet,這個packet便會在pipeline里傳給第二個、第三個…DataNode。

    在pipeline反方向上,逐個發送ack(命令正確應答),最終由pipeline中第一個DataNode節點將ack發送給client。

  5、寫完數據,關閉輸輸出流.

  6、發送完成信號給NameNode。

更通俗易懂的圖:

四、機架感知(副本節點的選擇)

  1. 第一個副本在client所處的節點上。如果客戶端在集群外,隨機選一個
  2. 第二個副本和第一個副本位於相同機架,隨機節點。
  3. 第三個副本位於不同機架,隨機節點

五、DFSOutputStream內部原理

 

1、創建Packet

    Client寫數據時,會將字節流數據緩存到內部的緩沖區中,當長度滿足一個Chunk大小(512B)時,便會創建一個Packet對象,然后向該Packet對象中寫Chunk

  的Checksum校驗和數據,以及實際數據塊Chunk Data,校驗和數據是基於實際數據塊計算得到的。每次滿足一個Chunk大小時,都會向Packet中寫上述數據內容,

  直到達到一個Packet對象大小(64K),就會將該Packet對象放入到dataQueue隊列中,等待DataStreamer線程取出並發送到DataNode節點。

2、發送Packet

    DataStreamer線程從dataQueue隊列中取出Packet對象,放到ackQueue隊列中,然后向DataNode節點發送這個Packet對象所對應的數據

3、接收ack

    發送一個Packet數據包以后,會有一個用來接收ack的ResponseProcessor線程,如果收到成功的ack,則表示一個Packet發送成功,ResponseProcessor線程會將

  ackQueue隊列中對應的Packet刪除,在發送過程中,如果發生錯誤,所有未完成的Packet都會從ackQueue隊列中移除掉,然后重新創建一個新的Pipeline,排除掉出錯的

  那些DataNode節點,接着DataStreamer線程繼續從dataQueue隊列中發送Packet。


免責聲明!

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



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