Hadoop介紹-4.Hadoop中NameNode、DataNode、Secondary、NameNode、JobTracker TaskTracker
Hadoop是一個能夠對大量數據進行分布式處理的軟體框架,實現了Google的MapReduce編程模型和框架,能夠把應用程式分割成許多的 小的工作單元,並把這些單元放到任何集群節點上執行。在MapReduce中,一個準備提交執行的應用程式稱為「作業(job)」,而從一個作業劃分出 得、運行於各個計算節點的工作單元稱為「任務(task)」。此外,Hadoop提供的分布式文件系統(HDFS)主要負責各個節點的數據存儲,並實現了 高吞吐率的數據讀寫。
在分布式存儲和分布式計算方面,Hadoop都是用從/從(Master/Slave)架構。在一個配置完整的集群上,想讓Hadoop這頭大 象奔跑起來,需要在集群中運行一系列後臺(deamon)程序。不同的後臺程序扮演不用的角色,這些角色由NameNode、DataNode、 Secondary NameNode、JobTracker、TaskTracker組成。其中NameNode、Secondary NameNode、JobTracker運行在Master節點上,而在每個Slave節點上,部署一個DataNode和TaskTracker,以便 這個Slave伺服器運行的數據處理程序能儘可能直接處理本機的數據。對Master節點需要特別說明的是,在小集群中,Secondary NameNode可以屬於某個從節點;在大型集群中,NameNode和JobTracker被分別部署在兩臺伺服器上。
我們已經很熟悉這個5個進程,但是在使用的過程中,我們經常遇到問題,那麼該如何入手解決這些問題。那麼首先我們需了解的他們的原理和作用。
1.Namenode介紹
Namenode 管理者文件系統的Namespace。它維護著文件系統樹(filesystem tree)以及文件樹中所有的文件和文件夾的元數據(metadata)。管理這些信息的文件有兩個,分別是Namespace 鏡像文件(Namespace image)和操作日誌文件(edit log),這些信息被Cache在RAM中,當然,這兩個文件也會被持久化存儲在本地硬碟。Namenode記錄著每個文件中各個塊所在的數據節點的位置信息,但是他並不持久化存儲這些信息,因為這些信息會在系統啟動時從數據節點重建。
客戶端(client)代表用戶與namenode和datanode交互來訪問整個文件系統。客戶端提供了一些列的文件系統接口,因此我們在編程時,幾乎無須知道datanode和namenode,即可完成我們所需要的功能。
1.1Namenode容錯機制
沒有Namenode,HDFS就不能工作。事實上,如果運行namenode的機器壞掉的話,系統中的文件將會完全丟失,因為沒有其他方法能夠將位於不同datanode上的文件塊(blocks)重建文件。因此,namenode的容錯機制非常重要,Hadoop提供了兩種機制。
第一種方式是將持久化存儲在本地硬碟的文件系統元數據備份。Hadoop可以通過配置來讓Namenode將他的持久化狀態文件寫到不同的文件系統中。這種寫操作是同步並且是原子化的。比較常見的配置是在將持久化狀態寫到本地硬碟的同時,也寫入到一個遠程掛載的網絡文件系統。
第二種方式是運行一個輔助的Namenode(Secondary Namenode)。 事實上Secondary Namenode並不能被用作Namenode它的主要作用是定期的將Namespace鏡像與操作日誌文件(edit log)合併,以防止操作日誌文件(edit log)變得過大。通常,Secondary Namenode 運行在一個單獨的物理機上,因為合併操作需要占用大量的CPU時間以及和Namenode相當的內存。輔助Namenode保存著合併後的Namespace鏡像的一個備份,萬一哪天Namenode宕機了,這個備份就可以用上了。
但是輔助Namenode總是落後於主Namenode,所以在Namenode宕機時,數據丟失是不可避免的。在這種情況下,一般的,要結合第一種方式中提到的遠程掛載的網絡文件系統(NFS)中的Namenode的元數據文件來使用,把NFS中的Namenode元數據文件,拷貝到輔助Namenode,並把輔助Namenode作為主Namenode來運行。
2、Datanode介紹
Datanode是文件系統的工作節點,他們根據客戶端或者是namenode的調度存儲和檢索數據,並且定期向namenode發送他們所存儲的塊(block)的列表。
集群中的每個伺服器都運行一個DataNode後臺程序,這個後臺程序負責把HDFS數據塊讀寫到本地的文件系統。當需要通過客戶端讀/寫某個 數據時,先由NameNode告訴客戶端去哪個DataNode進行具體的讀/寫操作,然後,客戶端直接與這個DataNode伺服器上的後臺程序進行通 信,並且對相關的數據塊進行讀/寫操作。
3、Secondary NameNode介紹
Secondary NameNode是一個用來監控HDFS狀態的輔助後臺程序。就想NameNode一樣,每個集群都有一個Secondary NameNode,並且部署在一個單獨的伺服器上。Secondary NameNode不同於NameNode,它不接受或者記錄任何實時的數據變化,但是,它會與NameNode進行通信,以便定期地保存HDFS元數據的 快照。由於NameNode是單點的,通過Secondary NameNode的快照功能,可以將NameNode的宕機時間和數據損失降低到最小。同時,如果NameNode發生問題,Secondary NameNode可以及時地作為備用NameNode使用。
3.1NameNode的目錄結構如下:
${dfs.name.dir}/current/VERSION
/edits
/fsimage
/fstime
3.2Secondary NameNode的目錄結構如下:
${fs.checkpoint.dir}/current/VERSION
/edits
/fsimage
/fstime
/previous.checkpoint/VERSION
/edits
/fsimage
/fstime
如上圖,Secondary NameNode主要是做Namespace image和Edit log合併的。
那麼這兩種文件是做什麼的?當客戶端執行寫操作,則NameNode會在edit log記錄下來,(我感覺這個文件有些像Oracle的online redo logo file)並在內存中保存一份文件系統的元數據。
Namespace image(fsimage)文件是文件系統元數據的持久化檢查點,不會在寫操作後馬上更新,因為fsimage寫非常慢(這個有比較像datafile)。
由於Edit log不斷增長,在NameNode重啟時,會造成長時間NameNode處於安全模式,不可用狀態,是非常不符合Hadoop的設計初衷。所以要周期性合併Edit log,但是這個工作由NameNode來完成,會占用大量資源,這樣就出現了Secondary NameNode,它可以進行image檢查點的處理工作。步驟如下:
(1) Secondary NameNode請求NameNode進行edit log的滾動(即創建一個新的edit log),將新的編輯操作記錄到新生成的edit log文件;
(2) 通過http get方式,讀取NameNode上的fsimage和edits文件,到Secondary NameNode上;
(3) 讀取fsimage到內存中,即加載fsimage到內存,然後執行edits中所有操作(類似OracleDG,應用redo log),並生成一個新的fsimage文件,即這個檢查點被創建;
(4) 通過http post方式,將新的fsimage文件傳送到NameNode;
(5) NameNode使用新的fsimage替換原來的fsimage文件,讓(1)創建的edits替代原來的edits文件;並且更新fsimage文件的檢查點時間。
整個處理過程完成。
Secondary NameNode的處理,是將fsimage和edites文件周期的合併,不會造成nameNode重啟時造成長時間不可訪問的情況。
4、JobTracker介紹
JobTracker後臺程序用來連接應用程式與Hadoop。用戶代碼提交到集群以後,由JobTracker決定哪個文件將被處理,並且為 不同的task分配節點。同時,它還監控所有的task,一旦某個task失敗了,JobTracker就會自動重新開啟這個task,在大多數情況下這 個task會被放在不用的節點上。每個Hadoop集群只有一個JobTracker,一般運行在集群的Master節點上。
下面我們詳細介紹:
4.1JobClient
我們配置好作業之後,就可以向JobTracker提交該作業了,然後JobTracker才能安排適當的TaskTracker來完成該作業。那麼MapReduce在這個過程中到底做了那些事情呢?這就是本文以及接下來的一片博文將要討論的問題,當然本文主要是圍繞客戶端在作業的提交過程中的工作來展開。先從全局來把握這個過程吧!
在Hadoop中,作業是使用Job對象來抽象的,對於Job,我首先不得不介紹它的一個大傢夥JobClient——客戶端的實際工作者。JobClient除了自己完成一部分必要的工作外,還負責與JobTracker進行交互。所以客戶端對Job的提交,絕大部分都是JobClient完成的,從上圖中,我們可以得知JobClient提交Job的詳細流程主要如下:
JobClient在獲取了JobTracker為Job分配的id之後,會在JobTracker的系統目錄(HDFS)下為該Job創建一個單獨的目錄,目錄的名字即是Job的id,該目錄下會包含文件job.xml、job.jar、job.split等,其中,job.xml文件記錄了Job的詳細配置信息,job.jar保存了用戶定義的關於job的map、reduce操縱,job.split保存了job任務的切分信息。在上面的流程圖中,我想詳細闡述的是JobClient是任何配置Job的運行環境,以及如何對Job的輸入數據進行切分。
4.2JobTracker
上面談到了客戶端的JobClient對一個作業的提交所做的工作,那麼這裡,就要好好的談一談JobTracker為作業的提交到底幹了那些個事情——一.為作業生成一個Job;二.接受該作業。
我們都知道,客戶端的JobClient把作業的所有相關信息都保存到了JobTracker的系統目錄下(當然是HDFS了),這樣做的一個最大的好處就是客戶端幹了它所能幹的事情同時也減少了伺服器端JobTracker的負載。下面就來看看JobTracker是如何來完成客戶端作業的提交的吧!哦。對了,在這裡我不得不提的是客戶端的JobClient向JobTracker正式提交作業時直傳給了它一個改作業的JobId,這是因為與Job相關的所有信息已經存在於JobTracker的系統目錄下,JobTracker只要根據JobId就能得到這個Job目錄。
對於上面的Job的提交處理流程,我將簡單的介紹以下幾個過程:
1.創建Job的JobInProgress
JobInProgress對象詳細的記錄了Job的配置信息,以及它的執行情況,確切的來說應該是Job被分解的map、reduce任務。在JobInProgress對象的創建過程中,它主要幹了兩件事,一是把Job的job.xml、job.jar文件從Job目錄copy到JobTracker的本地文件系統(job.xml->*/jobTracker/jobid.xml,job.jar->*/jobTracker/jobid.jar);二是創建JobStatus和Job的mapTask、reduceTask存隊列來跟蹤Job的狀態信息。
2.檢查客戶端是否有權限提交Job
JobTracker驗證客戶端是否有權限提交Job實際上是交給QueueManager來處理的。
3.檢查當前mapreduce集群能夠滿足Job的內存需求
客戶端提交作業之前,會根據實際的應用情況配置作業任務的內存需求,同時JobTracker為了提高作業的吞吐量會限制作業任務的內存需求,所以在Job的提交時,JobTracker需要檢查Job的內存需求是否滿足JobTracker的設置。
上面流程已經完畢,可以總結為下圖:
5、TaskTracker介紹
TaskTracker與負責存儲數據的DataNode相結合,其處理結構上也遵循主/從架構。JobTracker位於主節點,統領 MapReduce工作;而TaskTrackers位於從節點,獨立管理各自的task。每個TaskTracker負責獨立執行具體的task,而 JobTracker負責分配task。雖然每個從節點僅有一個唯一的一個TaskTracker,但是每個TaskTracker可以產生多個java 虛擬機(JVM),用於並行處理多個map以及reduce任務。TaskTracker的一個重要職責就是與JobTracker交互。如果 JobTracker無法準時地獲取TaskTracker提交的信息,JobTracker就判定TaskTracker已經崩潰,並將任務分配給其他 節點處理。
5.1TaskTracker內部設計與實現
Hadoop採用master-slave的架構設計來實現Map-Reduce框架,它的JobTracker節點作為主控節點來管理和調度用戶提交的作業,TaskTracker節點作為工作節點來負責執行JobTracker節點分配的Map/Reduce任務。整個集群由一個JobTracker節點和若幹個TaskTracker節點組成,當然,JobTracker節點也負責對TaskTracker節點進行管理。在前面一系列的博文中,我已經比較系統地講述了JobTracker節點內部的設計與實現,而在本文,我將對TaskTracker節點的內部設計與實現進行一次全面的概述。
TaskTracker節點作為工作節點不僅要和JobTracker節點進行頻繁的交互來獲取作業的任務並負責在本地執行他們,而且也要和其它的TaskTracker節點交互來協同完成同一個作業。因此,在目前的Hadoop-0.20.2.0實現版本中,對工作節點TaskTracker的設計主要包含三類組件:服務組件、管理組件、工作組件。服務組件不僅負責與其它的TaskTracker節點而且還負責與JobTracker節點之間的通信服務,管理組件負責對該節點上的任務、作業、JVM實例以及內存進行管理,工作組件則負責調度Map/Reduce任務的執行。這三大組件的詳細構成如下:
下面來詳細的介紹這三類組件:
服務組件
TaskTracker節點內部的服務組件不僅用來為TaskTracker節點、客戶端提供服務,而且還負責向TaskTracker節點請求服務,這一類組件主要包括HttpServer、TaskReportServer、JobClient三大組件。
1.HttpServer
TaskTracker節點在其內部使用Jetty Web容器來開啟http服務,這個http服務一是用來為客戶端提供Task日誌查詢服務,二是用來提供數據傳輸服務,即在執行Reduce任務時是通過TaskTracker節點提供的該http服務來獲取屬於自己的map輸出數據。這裡需要詳細介紹的是與該服務相關的配置參數,集群管理者可以通過TaskTracker節點的配置文件來配置該服務地址和埠號,對應的配置項為:mapred.task.tracker.http.address。同時,為了能夠靈活的控制該該服務的吞吐量,管理者還可以設置該http服務的內部工作線程數量,對應的配置為:tasktracker.http.threads。
2.Task Reporter
TaskTracker節點在接收到JobTracker節點發送過來的Map/Reduce任務之後,會把它們交給JVM實例來執行,而自己則需要收集這些任務的執行進度信息,這就使得Task在JVM實例中執行的時候需要不斷地向TaskTracker節點報告當前的執行情況。雖然TaskTracker節點和JVM實例在同一臺機器上,但是它們之間的進程通信卻是通過網絡I/O來完成的(此處並不討論這種通信方式的性能),也就是TaskTracker節點在其內部開啟一個埠來專門為任務實例提供進度報告服務。該服務地址可以通過配置項mapred.task.tracker.report.address來設置,而服務內部的工作線程的數量取2倍於該TaskTracker節點上的Map/Reduce Slot數量中的大者。
Hadoop介紹-4.Hadoop中NameNode、DataNode、Secondary、NameNode、JobTracker TaskTracker