HDFS,MapReduce,Yarn 的架構思想和設計原理

本篇文章,我先通過一個引子,然後按順序依次爲大家帶來 Hadoop 三大組件:HDFS,MapReduce,Yarn 的架構分析和原理介紹,希望大家看完都能有所收穫 。

1 引子

大數據就是將各種數據統一收集起來進行計算,發掘其中的價值。這些數據,既包括數據庫的數據,也包括日誌數據,還包括專門採集的用戶行爲數據;既包括企業內部自己產生的數據,也包括從第三方採購的數據,還包括使用網絡爬蟲獲取的各種互聯網公開數據 ...

 面對如此龐大的數據,如何存儲、如何有效利用大規模的服務器集羣處理計算纔是大數據技術的核心。

2HDFS 分佈式文件存儲架構

我們知道,Google 大數據 “三駕馬車” 的第一駕是 GFS(Google 文件系統),而 Hadoop 的第一個產品是 HDFS,可以說分佈式文件存儲是分佈式計算的基礎,也可見分佈式文件存儲的重要性。如果我們將大數據計算比作烹飪,那麼數據就是食材,而 Hadoop 分佈式文件系統 HDFS 就是燒菜的那口大鍋。

廚師來來往往,食材進進出出,各種菜餚層出不窮,而不變的則是那口大鍋。大數據也是如此,這些年來,各種計算框架、各種算法、各種應用場景不斷推陳出新,讓人眼花繚亂,但是大數據存儲的王者依然是 HDFS。

爲什麼 HDFS 的地位如此穩固呢?在整個大數據體系裏面,最寶貴、最難以代替的資產就是數據,大數據所有的一切都要圍繞數據展開。HDFS 作爲最早的大數據存儲系統,存儲着寶貴的數據資產,各種新的算法、框架要想得到人們的廣泛使用,必須支持 HDFS 才能獲取已經存儲在裏面的數據

所以大數據技術越發展,新技術越多,HDFS 得到的支持越多,我們越離不開 HDFS。HDFS 也許不是最好的大數據存儲技術,但依然最重要的大數據存儲技術

HDFS 的架構 ,如下圖所示:

HDFS 可以將數千臺服務器組成一個統一的文件存儲系統,其中 NameNode 服務器充當文件控制塊的角色,進行文件元數據管理,即記錄文件名、訪問權限、數據存儲地址等信息,而真正的文件數據則存儲在 DataNode 服務器上。

DataNode 以塊爲單位存儲數據,所有的塊信息,比如 塊 ID、塊所在的服務器 IP 地址等,都記錄在 NameNode 服務器上,而具體的塊數據存儲在 DataNode 服務器上。

理論上,NameNode 可以將所有 DataNode 服務器上的所有數據塊都分配給一個文件,也就是說,一個文件可以使用所有服務器的硬盤存儲空間 。

此外,HDFS 爲了保證不會因爲磁盤或者服務器損壞而導致文件損壞,還會對數據塊進行復制,每個數據塊都會存儲在多臺服務器上,甚至多個機架上。

3MapReduce 大數據計算架構

大數據計算的核心思路是 移動計算比移動數據更划算。既然計算方法跟傳統計算方法不一樣,移動計算而不是移動數據,那麼用傳統的編程模型進行大數據計算就會遇到很多困難,因此 Hadoop 大數據計算使用了一種叫作 MapReduce 的編程模型。

其實 MapReduce 編程模型並不是 Hadoop 原創,甚至也不是 Google 原創,但是 Google 和 Hadoop 創造性地將 MapReduce 編程模型用到大數據計算上,立刻產生了神奇的效果,看似複雜的各種各樣的機器學習、數據挖掘、SQL 處理等大數據計算變得簡單清晰起來。

就好比數據存儲在 HDFS 上的最終目的還是爲了計算,通過數據分析或者機器學習獲得有益的結果。但是如果像傳統的應用程序那樣,把 HDFS 當做普通文件,從文件中讀取數據後進行計算,那麼對於需要一次計算數百 TB 數據的大數據計算場景,就不知道要算到什麼時候了。

大數據處理的經典計算框架是 MapReduce 。MapReduce 的核心思想是對數據進行分片計算。既然數據是以塊爲單位分佈存儲在很多服務器組成的集羣上,那麼能不能就在這些服務器上針對每個數據塊進行分佈式計算呢 ?

事實上,MapReduce 可以在分佈式集羣的多臺服務器上啓動同一個計算程序,每個服務器上的程序進程都可以讀取本服務器上要處理的數據塊進行計算,因此,大量的數據就可以同時進行計算了。但是這樣一來,每個數據塊的數據都是獨立的,如果這些數據塊需要進行關聯計算怎麼辦?

MapReduce 將計算過程分成了兩個部分:一部分是 map 過程,每個服務器上會啓動多個 map 進程,map 優先讀取本地數據進行計算,計算後輸出一個 <key,value> 集合;另一部分是 reduce 部分,MapReduce 在每個服務器上都會啓動多個 reduce 進程,然後對所有 map 輸出的 <key,value> 集合進行 shuffle 操作。所謂的 shuffle 就是將相同的 key 發送到同一個 reduce 進程中,在 reduce 中完成數據關聯計算 。

爲了更直觀的展示這個過程,下面以經典的 WordCount ,即統計所有數據中相同單詞的詞頻數據爲例,來認識 map 和 reduce 的處理過程 。

假設原始數據有兩個數據塊,MapReduce 框架啓動了兩個 map 進程進行處理,它們分別讀入數據 。map 函數會對輸入數據進行分詞處理,然後針對每個單詞輸出 <單詞,1> 這樣的 < key,value > 結果 。

然後 MapReduce 框架進行 shuffle 操作,相同的 key 發送給同一個 reduce 進程,reduce 的輸入就是 <key ,value 的列表> 這樣的結構,即相同 key 的 value 合併成了一個列表。

在這個示例中,這個 value 列表就是由很多個 1 組成的列表。reduce 對這些 1 進行求和操作,就得到了每個單詞的詞頻結果了。

示例代碼如下:

上面的源代碼描述的是 map 和 reduce 進程合作完成數據處理的過程,那麼這些進程是如何在分佈式的服務器集羣上啓動的呢?數據是如何流動並最終完成計算的呢?

我們以 Hadoop 1 爲例,帶領大家一起看下這個過程。

MapReduce1 主要有 JobTracker 和 TaskTracker 這兩種角色,JobTracker 在 MapReduce 的集羣只有一個,而 TaskTracker 則和 DataNode 一起啓動在集羣的所有服務器上。

MapReduce 應用程序 JobClient 啓動後,會向 JobTracker 提交作業,JobTracker 根據作業中輸入的文件路徑分析需要在哪些服務器上啓動 map 進程,然後就在這些服務器上的 TaskTracker 發送任務命令。

TaskTracker 收到任務後,啓動一個 TaskRunner 進程下載任務對應的程序,然後反射加載程序中的 map 函數,讀取任務中分配的數據塊,並進行 map 計算。map 計算結束後,TaskTracker 會對 map 輸出進行 shuffle 操作,然後 TaskRunner 加載 reduce 函數進行後續計算 。

4Yarn 資源調度框架

在 MapReduce 應用程序的啓動過程中,最重要的就是要把 MapReduce 程序分發到大數據集羣的服務器上,在上文介紹的 Hadoop 1 中,這個過程主要是通過 TaskTracker 和 JobTracker 通信來完成。

但是這種架構方案有什麼缺點呢?

服務器集羣資源調度管理和 MapReduce 執行過程耦合在一起,如果想在當前集羣中運行其他計算任務,比如 Spark 或者 Storm,就無法統一使用集羣中的資源了。

在 Hadoop 早期的時候,大數據技術就只有 Hadoop 一家,這個缺點並不明顯。但隨着大數據技術的發展,各種新的計算框架不斷出現,我們不可能爲每一種計算框架部署一個服務器集羣,而且就算能部署新集羣,數據還是在原來集羣的 HDFS 上。

所以我們需要把 MapReduce 的資源管理和計算框架分開,這也是 Hadoop 2 最主要的變化,就是將 Yarn 從 MapReduce 中分離出來,成爲一個獨立的資源調度框架

Yarn 的設計思路也非常有趣。

首先,爲了避免功能的高度耦合,你得將原 JobTracker 的功能進行拆分

其次,一個集羣多個框架,即在一個集羣上部署一個統一的資源調度框架 YARN,在 YARN 之上可以部署各種計算框架。

最終形成 Yarn 的整體架構如下所示:

從圖上看,Yarn 包括兩個部分:一個是資源管理器(Resource Manager),一個是節點管理器(Node Manager)。這也是 Yarn 的兩種主要進程:ResourceManager 進程負責整個集羣的資源調度管理,通常部署在獨立的服務器上;NodeManager 進程負責具體服務器上的資源和任務管理,在集羣的每一臺計算服務器上都會啓動,基本上跟 HDFS 的 DataNode 進程一起出現。

具體說來,資源管理器又包括兩個主要組件:調度器和應用程序管理器。調度器其實就是一個資源分配算法,根據應用程序(Client)提交的資源申請和當前服務器集羣的資源狀況進行資源分配。

Yarn 內置了幾種資源調度算法,包括 Fair Scheduler、Capacity Scheduler 等,你也可以開發自己的資源調度算法供 Yarn 調用。Yarn 進行資源分配的單位是容器(Container),每個容器包含了一定量的內存、CPU 等計算資源,默認配置下,每個容器包含一個 CPU 核心。

容器由 NodeManager 進程啓動和管理,NodeManger 進程會監控本節點上容器的運行狀況並向 ResourceManger 進程彙報。

應用程序管理器負責應用程序的提交、監控應用程序運行狀態等。應用程序啓動後需要在集羣中運行一個 ApplicationMaster,ApplicationMaster 也需要運行在容器裏面。

每個應用程序啓動後都會先啓動自己的 ApplicationMaster,由 ApplicationMaster 根據應用程序的資源需求進一步向 ResourceManager 進程申請容器資源,得到容器以後就會分發自己的應用程序代碼到容器上啓動,進而開始分佈式計算。

5 巨人的肩膀

1、《從零開始學大數據》

2、《架構師的自我修煉》

3、 https://www.cnblogs.com/yszd/p/10885222.htm 

4、 http://hadoop.apache.org/ 

6 小結

本期內容簡單爲大家介紹了 Hadoop 三大組件的架構思想和原理,對於一些非重點的內容並未詳細展開介紹,大家可以自行了解學習。如果本期內容對你有點幫助,記得來發三連支持一下 ~ 

看完本文有收穫?請轉發分享給更多人

關注「大數據與機器學習文摘」,成爲 Top 1%

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/aUX3ZguVyNl_35of0YhznA