探秘HDFS——發展歷史、核心概念、架構、工作機制 (上)|博文精選

2019-10-19     科技百分百

戳藍字「CSDN雲計算關注我們哦!

作者 | Mr-Bruce

轉自 | CSDN博客

責編 | 阿禿

幾周前,筆者做了一個與HDFS有關的技術分享,以知識普及為目的,主要分享了Hadoop發展歷史、HDFS核心概念、整體架構、工作機制等內容。本文大部分內容來自於當時的Slides,分上下兩篇闡述。

HDFS,全稱Hadoop Distributed File System,顧名思義,是Hadoop裡面的分布式文件系統。在諸多大數據架構設計中,都能看到最底層是HDFS,用於數據的持久化。在Hadoop系統中(以2.7.3版本為例),HDFS只是其中一個組件,另外三個組件分別是:YARN,負責集群的資源管理;MapReduce,大數據計算引擎;Hadoop Common,相關公共庫。從架構拆分和接口通用化的角度來看,這四個組件都設計的很好,儘管最近幾年MapReduce逐漸被Spark、Flink這樣綜合型的內存型計算引擎替代,但是其他三個組件依然被廣泛使用在各種業務場景。

筆者所在的大數據項目主要使用Spark作為計算引擎,數據存放在AWS S3中,HDFS並沒有被重度使用,主要用在以下三個場景,用來保證Spark Streaming處理過程中的數據完整性(不多、不少)。

  • 為了保證在處理過程中Crash後,程序能恢復起來繼續處理,需要記錄Spark Streaming Checkpoint數據;

  • 為了保證已經接收、尚未處理的數據不丟失,需要依靠Spark Streaming WAL機制,即將接收的數據持久化;

  • 為了保證一段時間內沒有重複數據,需要記錄歷史數據的Hash值。

因為HDFS並不是整個項目的核心,所以參照業界用法就去用了,也沒有詳細的研究。上線後一年半時間內,陸續發生了5個與HDFS相關的CASE,占了近一半。且不論是否應該在上述場景去用HDFS,就發生的問題來看,主要是因為我們當時對HDFS的認知不夠。因此,這裡跟大家分享些筆者當前對HDFS的部分認識,期望能幫助到同道中人。

Hadoop發展歷史

在了解HDFS是什麼、怎麼工作之前,先來看看HDFS是在什麼樣的業務場景下被創造出來的。筆者這裡整理了2012年之前Hadoop的發展歷史,這一時間段也是Hadoop從萌生到飛速發展的階段。要談Hadoop的發展歷史,就不得不提到一個人:Doug Cutting,他是Apache Lucene、Nutch、Hadoop、Avro的創始人,為Apache社區作出了重要貢獻,目前在Cloudera擔任首席架構師。有意思的是,Hadoop的名字,就是他以自己兒子的一個玩具名來命名的。

階段一:孵化

上個世紀90年代,網際網路信息開始呈現爆炸式增長,「搜索」成為一個熱門方向。1997年,Doug開始研發Lucene項目,一個全文搜索引擎庫。比如,有100篇文章,給一個關鍵詞「飛機」,從中搜索出包含關鍵詞的文章。要實現這個功能,需要先將每篇文章分詞,建立倒排索引,然後根據關鍵詞來匹配打分,從而找出相關的文章。目前如日中天的Elasticsearch技術,便是基於Lucene來實現的,可見該項目的前瞻性與實用性。2001年,Doug將Lucene開源到Apache,之後很快成長為TOP項目。

2002年,Doug開始研發Nutch項目,用於爬取全網信息,然後用Lucene建立索引,從而提供網際網路搜索。但是,單靠一台機器是無法處理全網信息的。於是,Doug開始研究如何利用多台機器協調起來同時處理,即分布式存儲與計算技術。到2003年底,他實現了用四台機器來處理信息。但是,面對爆炸式的全網信息,四台機器還是太少了,而他的架構已經無法支持進一步擴展。就在Doug一籌莫展時,Google發表了論文Google File System,闡述了Google內部對分布式文件系統的理解和實現方式。

2004年,Doug根據GFS論文的指導,在Nutch項目中實現了DFS系統,這就是最早版的HDFS,只是當時叫NDFS。有了分布式存儲系統後,Doug開始思考如何在這樣的底層存儲上來重構之前的計算引擎,而就在年底,Google又發表了MapReduce論文。2005年,Doug實現了Nutch MapReduce,並基於MapReduce對Nutch進行了重構。

階段二:出世與成長

2006年,是Hadoop正式面世的一年。這一年,Doug將DFS和MapReduce從Nutch項目中剝離,組建了Hadoop項目。同年,Yahoo!開始全面轉移到Hadoop陣地,並聘請Doug作為項目轉型的架構師。到年底,Yahoo!的Hadoop集群達到了600台機器。

2007年,Twitter、Facebook、LinkedIn相繼加入Hadoop陣營。同年底,Yahoo!的集群達到1000台機器。

2008年,是Hadoop發展很重要的一年。這一年,Hadoop成長為Apache Top項目,HBase、Hive、Pig、Zookepper等基於Hadoop的項目相繼誕生,並貢獻給開源社區,整個Hadoop的生態體系構成。同年,一個新興的公司Cloudera成立,基於Hadoop提供專業的解決方案。

2009年,Amazon提供EMR雲服務,用戶不用擔心機器的維護、擴展,只需要關注自己的業務(PS:筆者當前的大數據服務都是跑在EMR中的)。同年8月,Doug加入Cloudera。2011年,另一家公司Hortoworks成立,跟Cloudera一樣,提供大數據解決方案。

階段三:飛升

2012年,Hadoop迎來了一次大的改動,成為Hadoop v2。除了很多接口、內部實現的優化外,最重要的是兩點:

  • 將YARN分拆出來,作為獨立的資源管理模塊;

  • 構建HDFS的HA和Federation解決方案,提高HDFS的高可用和擴展性。

到這一年底,Yahoo!的集群達到了42000台機器。2012年之後,到2016年,Hadoop平穩發展,被越來越多的公司引入使用。

總結來說,Hadoop是由Doug創建,最初是為了解決全網信息爬取與處理的問題,後來被Yahoo!發揚光大,在全社區的貢獻下迅速構建了自己的生態體系,對大數據處理的發展影響深遠。值得一提的是,隨著雲存儲和諸如Spark、Flink這樣內存型計算引擎的快速發展,2016年之後,Hadoop開始逐漸走下坡路。

核心概念

HDFS有兩個核心特徵:分布式、文件系統。從文件系統的角度來看,HDFS提供了一個統一的命名空間——目錄樹來組織文件,其操作命令的形式跟Linux作業系統基本保持一致,比如下圖中的"hdfs dfs -ls /"命令。目錄樹,是邏輯上的概念,用來屏蔽底層複雜的存儲和相關操作的細節,讓用戶感覺像在操作本地文件系統一樣。

從分布式的角度來看,一個文件可能會被切割成多個數據塊,分散存儲到多台機器上。數據塊,是物理上的概念,決定了文件的具體存儲形式。以下圖為例,文件"7572c-4427-81e1-bd111c6f01720.parquet" 大約500MB,會被分割為4個Block(默認一個Block的大小為128MB),假設集群有2台機器,就會每台機器分配兩個Block。另一方面,Hadoop在設計和使用上,有一個前提:允許集群中少量機器在某個時刻發生故障。為了達到這個目的,需要將文件拷貝多份放在不同的機器上,即Replica。比如,這裡的2台機器,會分別備份另一台機器上的數據塊(Replica設置為2)。

為什麼需要引入數據塊?其實是我們常說的「分而治之」的思想。假設沒有數據塊,直接以整體的形式存儲一個文件,就容易出現下面問題:

  • 集群中的機器使用不均勻。比如將一個20GB的文件完整存放到機器A上,勢必會導致機器A的負載更重。


  • 故障恢復慢。對於一個20GB文件,如果所在的某台機器故障了,整個系統需要重新搬移數據,保持足夠的Replica時,需要一次性移動20GB的數據,會帶來較高的負載。


  • 無法並行加載文件。文件作為整體存儲時,很難利用並行計算的優勢來並行加載文件。

下圖所示為一個數據塊(Block)的相關信息,上面部分是在WebHDFS UI上看到的信息,下面部分是該數據塊具體所在的機器上的信息。對於每一個數據塊,都有一個映射關係:文件名稱(包括路徑) -> Block Id -> Block所在機器,這個關係對數據塊的維護至關重要。

架構

HDFS的架構,可以從兩個角度來看:一個是由哪些組件構成,一個是組件之間如何通信。整個HDFS系統包含Client和Server兩部分:Client是發起操作的一方,可以是HDFS自帶的工具,也可以是通過API調用的程序(第三方庫、業務程序等);Server是提供存儲服務的一方,包括一個Name Node和多個Data Node。Name Node負責維護文件目錄樹、Block映射關係等元信息,Data Node負責具體的數據存儲。綜合來看,系統由三部分組成:Client、Name Node、Data Node。

這三個組件之間的通信關係,可以歸納為三方面:

  • Client向Name Node、Data Node發起通信。Client發起的文件操作主要為讀、寫、修改屬性,這些操作都會先跟Name Node交互,拿到返回信息後根據情況向相應的Data Node發起交互。

  • Data Node向Name Node發起通信。Data Node會定期向Name Node發送Heartbeat、Block Report信息,Name Node收到後作出判斷,並返回相關指令給Data Node,Data Node收到返回結果後,會根據情況做出進一步操作。Name Node不會主動向Data Node發起通信,只是被動地響應Data Node的通信。

  • Data Node之間的通信。Data Node之間在某些特定場景下會相互交互,比如寫操作時的數據複製、節點均衡時的數據移動。

這些通信關係是整個HDFS工作的核心,下一節筆者將進一步闡述在其之上的各種工作機制。




文章來源: https://twgreatdaily.com/zh-sg/1LzS5W0BMH2_cNUgvKwR.html