1. 程式人生 > >Hadoop之HDFS

Hadoop之HDFS

src 輸出 about lin pen 中一 文件是否存在 分配 input

  HDFS即Hadoop Distributed File System分布式文件系統,它的設計目標是把超大數據集存儲到分布在網絡中的多臺普通商用計算機上,並且能夠提供高可靠性和高吞吐量的服務。分布式文件系統要比普通磁盤文件系統復雜,因為它要引入網絡編程,分布式文件系統要容忍節點故障也是一個很大的挑戰。

技術分享圖片技術分享圖片 Namenode 和 Datanode   HDFS采用master/slave架構。一個HDFS集群是一個Namenode和一定數量的Datanode組成。Namenode是一個中心服務器,負責管理文件系統的namespace和客戶端對文件的訪問。Datenode在集群中一般是一個節點一個,負責管理節點上他們附帶的存儲。在內部,一個文件其實分成一個或多個block,這些block存儲在Datanode集合裏。Namenode執行文件系統的namespace操作,例如打開、關閉、重命名文件和目錄,同時決定block到具體Datanode節點的映射。Datanode在Namenode的指揮下進行block的創建、刪除和復制。Namenode和Datenode都是設計成可以跑在普通的廉價的運行linux的機器上。HDFS采用java語言開發,因此可以部署在很大範圍的機器上。一個典型的部署場景是一臺機器跑一個單獨的Namenode節點,集群中的其他機器各跑一個Datanode實例。這個架構並不排除一臺機器上跑多個Datanode,不過這比較少見。   單個節點的Namenode大大簡化了系統的架構。Namenode負責保管和管理所有的HDFS元數據,因而用戶數據就不需要通過Namenode(也就是說文件數據的讀寫是直接在Datanode上)。 文件系統的namespace
  HDFS支持傳統的層次型文件組織,與大多數其他文件系統類似,用戶可以創建目錄,並在其間創建、刪除、移動和重命名文件。HDFS不支持user quotas和訪問權限,也不支持鏈接,不過當前的架構並不排除實現這些特性。Namenode維護文件系統的namespace,任何對文件系統namespace和文件屬性的修改將被Namenode記錄下來。應用可以設置HDFS保存的文件的副本數目,文件副本的數目稱為文件的relication因子,這個信息也是由Namenode保存。 數據復制   HDFS被設計成在一個大集群中可以跨機器地可靠地存儲海量地文件。它將每個文件存儲成block序列,除了最後一個block,所有的block都是同樣的大小。文件的所有bolck為了容錯都會被復制。每個文件的block大小和replication因子都是可配置的。Replication因子可以在文件創建的時候配置,以後也可以改變。HDFS中的文件是write-one,並且嚴格要求在任何時候只有一個writer。Namenode全權管理block的復制,它周期性地從集群中的每個Datanode接收心跳包和一個Blockreport。心跳包的接收表示該Datanode節點正常工作,而Blockreport包括了該Datanode上所有的block組成的列表。 元數據塊
  元數據(Metadata)是描述其它數據的數據(data about other data),或者說是用於提供某種資源的有關信息的結構數據(structured data)。   元數據包括:     -文件系統目錄樹信息       -文件名,目錄名       -文件和目錄的從屬關系       -文件和目錄的大小,創建及最後訪問時間       -權限     -文件和塊的對應關系       -文件由哪些塊組成     -塊的存放位置       -機器名,塊ID 數據塊    兼容HDFS的應用都是處理大數據集合的。這些應用都是寫數據一次,讀卻是一次到多次,並且讀的速度要滿足流式讀。HDFS支持文件的write-once-read-many語義。一個典型的block大小是64MB,因而,文件總是按照64M切分成chunk,每個chunk存儲於不同的Datanode。   在傳統的塊存儲介質中,塊是讀寫的最小數據單位(扇區)   傳統文件系統基於存儲塊進行操作   HDFS也使用了塊的概念,默認64MB     -可針對每個文件配置,由客戶端指定     -每個塊有一個自己的全局ID   HDFS將一個文件分為一個或數個塊來存儲     -每個塊是一個獨立的存儲單位     -以塊為單位在集群服務器上分配存儲   與傳統文件系統不同的是,如果實際數據沒有達到塊大小,則並不實際占用磁盤空間     -如果一個文件是200M,則它會被分為4個塊:64+64+64+8   當一個文件大於集群中任意一個磁盤的時候,文件系統可以充分利用集群中所有的磁盤;管理塊使底層的存儲子系統相對簡單;塊更加適合備份,從而為容錯和高可用性的實現帶來方便;最重要的使,采用塊方式,實現了名字與位置的分離,實現了存儲位置的獨立性。 HDFS讀寫策略
  數據讀策略   技術分享圖片

  1、客戶端調用FileSystem實例的open方法,獲得這個文件對應的輸入流InputStream。

  2、通過RPC遠程調用NameNode,獲得NameNode中此文件對應的數據塊保存位置,包括這個文件的副本的保存位置(主要是各DataNode的地址)

  3、獲得輸入流之後,客戶端調用read方法讀取數據。選擇最近的DataNode建立連接並讀取數據。

  4、如果客戶端和其中一個DataNode位於同一機器(比如MapReduce)過程中的mapper 和 reducer ),那麽就會直接從本地讀取數據。

  5、到達數據塊末端,關閉與這個DataNode的連接,然後重新查找下一個數據塊。

  6、不斷執行第2-5步直到數據全部讀完。

  7、客戶端調用close,關閉輸入流DF S InputStream。

數據寫策略

  技術分享圖片

  1、客戶端調用FileSystem實例的create方法,創建文件。NameNode通過一些檢查,比如文件是否存在,客戶端是否擁有創建權限等;通過檢查之後,在NameNode添加文件信息。註意,因為此時文件沒有數據,所以NameNode上也沒有文件數據塊的信息。

  2、創建結束之後,HDFS會返回一個輸出流,DFSDataOutputStream給客戶端。

  3、客戶端調用輸出流DFSDataOutPutStream的write方法向HDFS中對應的文件寫入數據。

  4、數據首先會被分包,這些分包會寫入一個輸出流的內部隊列Data隊列中,接收完數據分包,輸出流DFSDataOutputStream會向NameNode申請保存文件和副本數據塊的若幹個DataNode,這若幹個DataNode會形成一個數據傳輸管道。DFSDataOutputStream將數據傳輸給距離上最短的DataNode,這個DataNode接收到數據包之後會傳給下一個DataNode。數據在各DataNode之間通過管道流動,而不是全部由輸出流分發,以減少傳輸開銷。

  5、因為各DataNode位於不同機器上,數據需要通過網絡發送,所以,為了保證所有DataNode的數據都是準確的,接受到數據的DataNode要向發送者發送ACK。對於某個數據塊,只有當DFSDataOutputStream收到了所有DataNode的ACK,才能確認傳輸結束。DFSDataOutputStream內部專門維護了一個等待ACK隊列,這個隊列保存已經進入管道傳輸數據、但是並未被完全確認的數據包。

  6、不斷執行3-5步直到數據全部寫完,客戶端調用close關閉文件。

  7、DFSDataInputStream繼續等待直到所有數據寫入完畢並被確認,調用complete方法通知NameNode文件寫入完成。NameNode接受到complete消息之後,等待相應數量的副本寫入完畢後,告知客戶端。

Hadoop之HDFS