HDFS設計思想和相關概念

  一、HDFS簡介

  1、簡單介紹

  HDFS(Hadoop Distributed FileSystem),是Hadoop項目的兩大核心之一,源自於Google於2003年10月發表的GFS論文,是對GFS的開源實現。HDFS在最開始是作為Apache Nutch搜索引擎項目的基礎架構而開發的。

  HDFS在設計之初,就是要運行在通用硬件(commodity hardware)上,即廉價的大型服務器集羣上,因此,在設計上就把硬件故障作為一種常態來考慮,可以保證在部分硬件發生故障的情況下,仍然能夠保證文件系統的整體可用性和可靠性。

  HDFS有一下特點:

  HDFS是一個高度容錯性的系統,適合部署在廉價的機器上的分佈式文件系統。HDFS能提供高吞吐量的數據訪問,非常適合大規模數據集上的應用。HDFS放寬了一部分POSIX約束,來實現流式讀取文件系統數據的目的。HDFS也是一個易於擴展的分佈式文件系統

  2、HDFS設計目標

  a、大規模數據集

  HDFS用來處理很大的數據集。HDFS上的文件,大小一般都在GB至TB。因此同時,HDFS應該能提供整體較高的數據傳輸帶寬,能在一個集羣裏擴展到數百個節點。一個單一的HDFS實例應該能支撐千萬計的文件。目前在實際應用中,HDFS已經能用來存儲管理PB級的數據了。

  b、硬件錯誤

  我們應該知道,硬件組件發生故障是常態,而非異常情況。HDFS可能由成百上千的服務器組成,每一個服務器都是廉價通用的普通硬件,任何一個組件都有可能一直失效,因此錯誤檢測和快速、自動恢復是HDFS的核心架構目標,同時能夠通過自身持續的狀態監控快速檢測冗餘並恢復失效的組件。

  c、流式數據訪問

  流式數據,特點就是,像流水一樣,不是一次過來而是一點一點“流”過來,而處理流式數據也是一點一點處理。

  HDFS的設計要求是:能夠高速率、大批量的處理數據,更多地響應"一次寫入、多次讀取"這樣的任務。在HDFS上一個數據集,會被複制分發到不同的存儲節點中。而各式各樣的分析任務多數情況下,都會涉及數據集中的大部分數據。為了提高數據的吞吐量,Hadoop放寬了POSIX的約束,使用流式訪問來進行高效的分析工作

  d、簡化一致性模型

  HDFS應用需要一個“一次寫入多次讀取”的文件訪問模型。一個文件經過創建、寫入和關閉之後就不需要改變了。這一假設簡化了數據一致性問題,並且使高吞吐量的數據訪問成為可能。MapReduce應用或網絡爬蟲應用都非常適合這個模型。目前還有計劃在將來擴充這個模型,使之支持文件的附加寫操作。

  e、移動計算代價比移動數據代價低

  一個應用請求的計算,離它操作的數據越近就越高效,這在數據達到海量級別的時候更是如此。將計算移動到數據附近,比之將數據移動到應用所在之處顯然更好,HDFS提供給應用這樣的接口。

  f、可移植性

  HDFS在設計時就考慮到平台的可移植性,這種特性方便了HDFS作為大規模數據應用平台的推廣。

  3、HDFS的優缺點

  通過上述的介紹,我們可以發現HDFS的優點是:

  a、高容錯性:數據自動保存多個副本,副本丟失後,會自動恢復。b、適合批處理:移動計算而非數據、數據位置需要暴露給計算框架。c、適合大數據處理:GB、TB、甚至PB級數據、百萬規模以上的文件數量,1000以上節點規模。d、流式文件訪問:一次性寫入,多次讀取;保證數據一致性。e、可構建在廉價機器上:通過多副本提高可靠性,提供了容錯和恢復機制。

  而HDFS同樣有自己的缺點:

  1)不適合低延遲數據訪問

  HDFS的設計目標有一點是:處理大型數據集,高吞吐率。這勢必要以高延遲為代價的。因此HDFS不適合處理一些用户要求時間比較短的低延遲應用請求。

  2)不適合小文件存取

  一是因此存取大量小文件需要消耗大量的尋地時間(比如拷貝大量小文件與拷貝同等大小的一個大文件) 。

  二是因為namenode把元信息存儲在內存中,一個節點的內存是有限的。一個block元信息的內存消耗大約是150 byte。而存儲1億個block和1億個小文件都會消耗掉namenode 20GB內存,哪個適合?當然是1億個block(大文件)更省內存。

  3)不適合併發寫入、文件隨機修改

  HDFS上的文件只能有一個寫者,也僅僅支持append操作,不支持多用户對同一文件的寫操作,以及在文件任意位置進行修改。

  二、HDFS設計思想

  現在想象一下這種情況:有四個文件 0.5TB的file1,1.2TB的file2,50GB的file3,100GB的file4;有7個服務器,每個服務器上有10個1TB的硬盤。

  在存儲方式上,我們可以將這四個文件存儲在同一個服務器上(當然大於1TB的文件需要切分),我們需要使用一個文件來記錄這種存儲的映射關係吧。用户是可以通過這種映射關係來找到節點硬盤相應的文件的。那麼缺點也就暴露了出來:

  第一、負載不均衡。因為文件大小不一致,勢必會導致有的節點磁盤的利用率高,有的節點磁盤利用率低。

  第二、網絡瓶頸問題。一個過大的文件存儲在一個節點磁盤上,當有並行處理時,每個線程都需要從這個節點磁盤上讀取這個文件的內容,那麼就會出現網絡瓶頸,不利於分佈式的數據處理。

  我們來看看HDFS的設計思想:以下圖為例,來進行解釋。

HDFS設計思想和相關概念
  點擊添加圖片描述(最多60個字)編輯

  HDFS將50G的文件file3切成多個Block(存儲塊),每一個Block的大小都是固定的,比如128MB,它把這多個數據塊以多副本的行式存儲在各個節點上 ,再使用一個文件把哪個塊存儲在哪些節點上的映射關係存儲起來。有了這樣的映射關係,用户讀取文件的時候就會很容易讀取到。每個節點上都有這樣的Block數據,它會分開網絡瓶頸,利於分佈式計算,解決了上面的第二個問題。因為每個塊的大小是一樣的,所以很容易實現負載均衡,解決了上面的第一個問題。

  三、HDFS相關概念

  1、塊(Block)概念

  在我們熟知的Windows、Linux等系統上,文件系統會將磁盤空間劃分為每512字節一組,我們稱之為"磁盤塊",它是文件系統讀寫操作的最小單位。而文件系統的數據塊(Block)一般是磁盤塊的整數倍,即每次讀寫的數據量必須是磁盤塊的整數倍。

  在傳統的文件系統中,為了提高磁盤的讀寫效率,一般以數據塊為單位,而不是以字節為單位,比如機械硬盤包含了磁頭和轉動部件,在讀取數據時有一個尋道的過程,通國轉動盤片和移動磁頭的位置,來找到數據在機械硬盤中的存儲位置,然後才能進行讀寫。在I/O開銷中,機械硬盤的尋址時間時最耗時的部分,一旦找到第一條記錄,剩下的順序讀取效率是非常高的,因此以塊為單位讀寫數據,可以把磁盤尋道時間分攤到大量數據中。

  HDFS同樣引入了塊(Block)的概念,塊是HDFS系統當中的最小存儲單位,在hadoop2.0中默認大小為128MB。在HDFS上的文件會被拆分成多個塊,每個塊作為獨立的單元進行存儲。多個塊存放在不同的DataNode上,整個過程中 HDFS系統會保證一個塊存儲在一個數據節點上 。但值得注意的是 如果某文件大小或者文件的最後一個塊沒有到達128M,則不會佔據整個塊空間 。

  當然塊大小可以在配置文件中hdfs-default.xml中進行修改(此值可以修改)

  HDFS中的NameNode會記錄文件的各個塊都存放在哪個dataNode上,這些信息一般也稱為元信息(MetaInfo) 。元信息的存儲位置一般由dfs.namenode.name.dir來指定。

  而datanode是真實存儲文件塊的節點,塊在datanode的位置一般由dfs.datanode.data.dir來指定。

  HDFS上的塊為什麼遠遠大與傳統文件系統,是有原因的。目的是為了最小化尋址開銷時間。

  HDFS尋址開銷不僅包括磁盤尋道開銷,還包括數據庫的定位開銷,當客户端需要訪問一個文件時,首先從名稱節點獲取組成這個文件的數據塊的位置列表,然後根據位置列表獲取實際存儲各個數據塊的數據節點的位置,最後,數據節點根據數據塊信息在本地Linux文件系統中找到對應的文件,並把數據返回給客户端,設計一個比較大的塊,可以把尋址開銷分攤到較多的數據中,相對降低了單位數據的尋址開銷

  舉個例子: 塊大小為128MB,默認傳輸效率100M/s ,尋址時間為10ms,那麼尋址時間只佔傳輸時間的1%左右

  當然,塊也不能太大,因為另一個核心技術MapReduce的map任務一次只處理一個數據塊,如果任務太少,勢必會降低工作的並行處理速度。

  HDFS的塊概念,在解決了大數據集文件的存儲同時,不僅解決了文件存取的網絡瓶頸問題,還

  解決了大數據集文件的存儲:大文件分塊存儲在多個數據節點上,不必受限於單個節點的存儲容量。簡化系統設計:塊大小固定,單個節點的塊數量比較少,容易管理。元數據可以單獨由其他系統負責管理。適合數據備份:每個塊可以很容易的冗餘存儲到多個節點上,提高了系統的容錯性和可用性

  2、Namenode和Datanode

  HDFS集羣上有兩類節點,一類是管理節點(Namenode),一類是工作節點(Datanode)。而HDFS就是以管理節點-工作節點的模式運行的,在HDFS上,通常有一個Namenode和多個Datanode(一個管理者master,多個工作者slave)。

  作為master的NameNode負責管理分佈式文件系統的命名空間(NameSpace),即維護的是文件系統樹及樹內的文件和目錄。這些信息以 兩個核心文件(fsImage和editlog)的形式持久化在本地磁盤中。

  fsImage命名空間鏡像文件,用於維護文件系統樹以及文件樹中所有文件和目錄的元數據;操作日誌文件editlog中記錄了所有針對文件的創建、刪除、重命名等操作。namenode也記錄了每個文件的各個塊所在的datanode的位置信息,但並不持久化存儲這些信息,而是在系統每次啓動時掃描所datanode重構得到這些信息,也就是説保存在運行內存中。

  Namenode在啓動時,會將FsImage的內容加載到內存當中,然後執行EditLog文件中的各項操作,使得內存中的元數據保持最新。這個操作完成以後,就會創建一個新的FsImage文件和一個空的EditLog文件。名稱節點啓動成功並進入正常運行狀態以後,HDFS中的更新操作都被寫到EditLog,而不是直接寫入FsImage,這是因為對於分佈式文件系統而言,FsImage文件通常都很龐大,如果所有的更新操作都直接往FsImage文件中添加,那麼系統就會變得非常緩慢。相對而言,EditLog通常都要遠遠小於FsImage,更新操作寫入到EditLog是非常高效的。名稱節點在啓動的過程中處於“安全模式”,只能對外提供讀操作,無法提供寫操作。在啓動結束後,系統就會退出安全模式,進入正常運行狀態,對外提供寫操作。

  作為slave的Datanode是分佈式文件系統HDFS的工作節點,負責數據塊的存儲和讀取(會根據客户端或者Namenode的調度來進行數據的存儲和檢索),並且定期向Namenode發送自己所存儲的塊的列表。每個Datanode中的數據會被保存在本地Linux文件系統中。

  3、SecondaryNamenode

  在Namenode運行期間,HDFS會不斷髮生更新操作,這些更新操作不會直接寫到fsimage文件中,而是直接被寫入到editlog文件的,文件會越來越大。當Namenode重啓時,會加載fsimage加載到內存中,並且逐條執行editlog中的記錄,editlog文件大,就會導致整個過程變得非常緩慢,使得Namenode在啓動過程中長期處於“安全模式”,無法正常對外提供寫操作,影響了用户的使用。

  HDFS採用了SecondaryNameNode這個守護線程,可以定期完成editlog與fsImage的合併操作,減小editlog文件大小,縮短Namenode重啓時間;也可以作為Namenode的一個“檢查點”,將保存Namenode內存中的元數據信息,保存在fsimage鏡像文件中。

版權聲明:本文源自 網絡, 於,由 楠木軒 整理發佈,共 5027 字。

轉載請註明: HDFS設計思想和相關概念 - 楠木軒