一、簡介
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。
更通俗易懂的圖:
四、機架感知(副本節點的選擇)
- 第一個副本在client所處的節點上。如果客戶端在集群外,隨機選一個
- 第二個副本和第一個副本位於相同機架,隨機節點。
- 第三個副本位於不同機架,隨機節點
五、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。