五分鐘深入 Hadoop 內核

回顧

上篇文章我們說到,Hadoop 的工作下圖所示,負責把 mapper function 裝載到要運行 mapper 的機器上,然後執行 mapper function,之後負責把 mapper 的結果 shuffle 到要運行 reducer 的機器上,下載 reducer 運行得到最終結果。

那麼下面,我們就通過學習 Hadoop 的 component 架構,來理解 Hadoop 是怎麼做到這幾步的。

架構

JobTracker

我們上面說了:Hadoop 是一個很強大的 Framework, 那用戶怎麼使用呢?Hadoop 提供了一個叫做 JobTracker 的 component, 去等待用戶提交的Hadoop 任務。

具體說來, 用戶告訴 JobTracker 要運行什麼 mapper function 和 reducer function, 這個非常 make sense 對不對?Hadoop 就是要幫助用戶運行mapper 和 reducer, 不知道他們是什麼樣的怎麼行?

那 Mapper 和 Reducer 長什麼樣呢?

我們用 Java 舉例:用戶需要用一個 class 實現 Hadoop 定義的 Mapper 介面,用戶在這個 class 里提供 mapper function 的具體實現(當然 Hadoop 也支持別的語言),同樣的 reducer function 也是用戶實現 Reducer 介面的 class.

既然是 java, 這兩個 class 就會存在 jar 中,所以用戶要告訴 JobTracker 這個 jar 的路徑是什麼,也要告訴這個 jar 里,哪個 class 是 mapper, 哪個是 reducer. 只有這樣,JobTracker 才能幫助用戶把 mapper function 和 reducer function 部署到要運行的機器上。

除此之外,用戶還要告訴 JobTracker 要處理的數據在哪裡。實際上,數據存儲使用的是 HDFS 文件系統。我們之後會為大家詳細介紹,這裡請大家把 HDFS 想像成普通電腦里的文件系統就好,使用文件夾結構,比如 Linux 下的 /root, /usr, /etc ……

特別的是,HDFS 為了擴大容量,把文件存在很多台機器上,但用戶不需要知道分布的具體細節:只要告訴 HDFS 我要哪個目錄下的文件,HDFS 就會很神奇的找到相應的機器為用戶讀取數據(這就是分散式文件系統的特點)。

用戶需要告訴 JobTracker 這個任務里需要處理的數據數據存在 HDFS 的哪個目錄下面就 OK 啦。同樣的,用戶也要告訴 JobTracker 這個 Hadoop 任務的輸出在哪裡,通常也是一個HDFS上的目錄。

JobTracker 是以一個進程的形式運行的,一直等待用戶提交的任務。說白了,就好像大家玩過的掃雷:你打開這個遊戲後,那個窗口一直等待你點擊滑鼠。我們要記住的是一個 Hadoop cluster 里只有一個 JobTracker.

JobTracker 接收了用戶提交的任務之後它做什麼呢?

它就要挑選機器來執行 mapper / reducer function.

我們剛才說過,任務要處理的數據被 HDFS 管理。用戶是不知道數據存在哪些機器上的,而只要告訴 HDFS 一個目錄,它就知道到哪台機器取。

這樣 JobTracker 告訴 HDFS 用戶提交的輸入數據的路徑,HDFS 就會告訴 JobTracker 數據在哪台機器上,Job Tracker 也就可以把 mapper function 運行在那台機器上,這樣就可以達到非常好的運行效率:mapper function 處理本台機器上的數據。

我們知道 HDFS 和 Hadoop 運行在一組機器上,那這些機器有可能還在運行別的軟體,或者處理之前提交的任務。這就有可能造成:明明數據就在 Host A 上,但是 Host A 太忙,沒有空閑資源運行 mapper function, 這種情況怎麼辦呢?

這樣的情況下,JobTracker 可能就要退而求其次了:把 mapper function 運行在一個離數據很近的機器上,比如和數據所在機器網路連接速度很快的機器 Host B. 這樣,在數據從 Host A 讀取到 Host B之後,mapper function 就可以的繼續執行。

說起來簡單,但是前提是 JobTracker 需要知道每台機器忙不忙,否則它怎麼知道存數據的當前機器不能用,或者選擇另一個不忙的機器呢?

Hadoop 所做的就是為每一台機器定義 N 個 slot, 就是能同時運行 N 個 mapper function 或者 reducer function, 用幾個 slot 被佔用評斷機器忙不忙。

一個機器有幾個 slot 是機器管理員根據機器 cpu 和內存情況設定的,在用戶提交任務以前就定義好了。Jobtracker 通過追蹤每一台機器上還有幾個 slot可以用來判斷機器的繁忙程度。

這裡你是不是覺得 Hadoop 繞彎子?直接看每台機器 cpu 和 memory 不就好了,為什麼還通過 slot 表示?恭喜你,你已經有 Hadoop 2.0 architect 的水平了:) 我們之後討論哈。

之前說過 JobTracker 只是運行在一台機器上的一個進程,那它如何知道其他機器有哪些 slot 呢?

答案是:它是通過 TaskTracker 來完成的。

TaskTracker

TaskTracker 是運行在每一台機器上的一個 daemon. 它的首要任務就是 keep track of 本台機器有哪些 slot.

這個工作比較簡單:TaskTracker 啟動時,它從機器管理員寫的 config file 里讀出這台機器有幾個 slot; 當 JobTracker 分配給這台機器一個 mapper function 或者 reducer function, 那 TaskTracker 就會記錄下 slot 減少一個。

TaskTracker and Slots

TaskTracker 有一個 heartbeat 機制,就是每隔幾秒鐘或者幾分鐘向 JobTracker 發一個信息,告之當前機器還有幾個 free slot. 這樣,JobTracker 就知道所有 Hadoop 機器資源使用情況。那麼下次 JobTracker 收到用戶提交的任務時,就有足夠的信息決定向哪個機器分配 mapper 或 reducer 任務。

JobTracker task allocation to TaskTrackers

那麼當 JobTracker 決定了給機器 a, c, e, f (out of 機器 a-h) 分配任務之後,JobTracker 就向每一台機器發消息,告訴它你要執行的 mapper 或者 reducer function 是什麼。

在Java里,這一步就是告訴每一台機器 jar 的路徑,以及 mapper class 和 reducer class 的名稱。

如果分配的是 mapper function, JobTracker 還要告訴 TaskTracker mapper 要處理的數據路徑。我們之前提到了 JobTracker 會儘可能把 mapper 分配到數據所在的機器,這樣 mapper 可以從本地文件讀取數據了。

當 TaskTracker 得知所有這些信息之後,就可以運行 mapper/reducer.

我們之前說 Hadoop 會去執行 mapper function 和 reducer function, TaskTracker 就是 Hadoop 里負責這個任務的 component.

mapper function 和 reducer function 運行結束以後,TaskTracker 會報告給 JobTracker 運行結果。當所有 mapper 和 reducer 運行結束後,整個 Job 就完成了!

Hadoop / MapReduce 作為非常成熟的大數據架構,已經被部署在很多知名公司的實際系統中、發揮著重要作用,比如 Amazon, Facebook, Apple 等等。

除了並行處理數據外的優勢外,其對海量數據的處理和優化也非常有特色。

推薦閱讀:

OSDI 2016有哪些讓人眼前一亮的文章?
大數據計算框架除了 MapReduce 還有哪些呢,不應該是 MapReduce 去解決所有問題吧?
「分散式」「集群」「雲計算」三者是什麼區別呢?
分散式系統經典論文概述(1)
分散式系統之 Replication

TAG:大数据 | Hadoop | 分布式系统 |