前言
Hadoop是一個基于Java的分布式密集數(shù)據(jù)處理和數(shù)據(jù)分析的軟件框架。Hadoop在很大程度上是受Google在2004年白皮書中闡述的MapReduce技術(shù)的啟發(fā)。MapReduce工作原理是將任務分解為成百上千個小任務,然后發(fā)送到計算機集群中。每臺計算機再傳送自己那部分信息,MapReduce則迅速整合這些反饋并形成答案。簡單來說,就是任務的分解和結(jié)果的合成。
Hadoop的擴展性非常優(yōu)秀,Hadoop可處理分布在數(shù)以千計的低成本x86服務器計算節(jié)點中的大型數(shù)據(jù)。這種高容量低成本的組合引人注目,但Hadoop最吸引人的是其處理混合數(shù)據(jù)類型的能力。Hadoop可以管理結(jié)構(gòu)化數(shù)據(jù),以及諸如服務器日志文件和Web點擊流的數(shù)據(jù)。同時還可以管理以非結(jié)構(gòu)化文本為中心的數(shù)據(jù),如Facebook和Twitter。
1 Hadoop基本架構(gòu)
Hadoop 并不僅僅是一個用于存儲的分布式文件系統(tǒng),而是在由通用計算設(shè)備組成的大型集群上執(zhí)行分布式應用的框架。Apache Hadoop項目中包含了下列產(chǎn)品(見圖1)。
圖1 Hadoop基本組成
Pig和Hive是Hadoop的兩個解決方案,使得在Hadoop上的編程更加容易,編程人員不再需要直接使用Java APIs。Pig可加載數(shù)據(jù)、轉(zhuǎn)換數(shù)據(jù)格式以及存儲最終結(jié)果等一系列過程,從而優(yōu)化MapReduce 運算。
Hive 在Hadoop 中扮演數(shù)據(jù)倉庫的角色。Hive 可向HDFS添加數(shù)據(jù),并允許使用類似SQL的語言進行數(shù)據(jù)查詢。Chukwa是基于Hadoop集群的監(jiān)控系統(tǒng),簡單來說就是一個WatchDog。HBase是一個面向列的分布式存儲系統(tǒng),用于在Hadoop中支持大型稀疏表的列存儲數(shù)據(jù)環(huán)境。MapReduce用于超大型數(shù)據(jù)集的并行運算。HDFS 可以支持千萬級的大型分布式文件系統(tǒng)。Zookeeper提供分布式應用程序的協(xié)調(diào)服務,支持的功能包括配置維護、名字服務、分布式同步、組服務等。Avro是一個數(shù)據(jù)序列化系統(tǒng),用于支持大批量數(shù)據(jù)交換的應用。
Hadoop主要由HDFS和MapReduce引擎兩部分組成。最底層是HDFS,它存儲Hadoop集群中所有存儲節(jié)點上的文件,HDFS的上一層是MapReduce引擎,該引擎由JobTracker和TaskTrackers組成。
2 HDFS 淺析
管理網(wǎng)絡中跨多臺計算機存儲的文件系統(tǒng)稱為分布式文件系統(tǒng)。HDFS以流式數(shù)據(jù)訪問模式來存儲超大文件,運行于商用硬件集群上。
HDFS的構(gòu)建思路是這樣的:一次寫入、多次讀取是最高效的訪問模式。數(shù)據(jù)集通常由數(shù)據(jù)源生成或從數(shù)據(jù)源復制而來,接著長時間在此數(shù)據(jù)集上進行各類分析。每次分析會涉及該數(shù)據(jù)集的大部分數(shù)據(jù)甚至全部,因此讀取整個數(shù)據(jù)集的時間延遲比讀取第一條記錄的時間延遲更重要。
所謂商用硬件,Hadoop并不需要運行在昂貴且高可靠的硬件上。對于龐大的集群來說,節(jié)點故障的幾率還是非常高的。HDFS被設(shè)計成在遇到故障時能夠繼續(xù)運行且不讓用戶察覺到明顯的中斷。同時,商用硬件并非低端硬件。低端機器故障率遠高于更昂貴的機器。當用戶管理幾十臺、上百臺,甚至幾千臺機器時,便宜的零部件故障率更高,導致維護成本更高。
HDFS是為高數(shù)據(jù)吞吐量應用優(yōu)化的,這可能會以高時間延遲為代價。目前,對于低延遲的數(shù)據(jù)訪問需求,HBase是更好的選擇。
2.1 數(shù)據(jù)塊
每個磁盤都有默認的數(shù)據(jù)塊大小,這是磁盤進行數(shù)據(jù)讀/寫的最小單位。HDFS同樣也有塊的概念,默認為64 MB(很多情況下使用128 MB)。HDFS上文件也被劃分為多個分塊作為獨立的存儲單元。HDFS的塊比磁盤塊(一般為512字節(jié))大很多,其目的是為了最小化尋址開銷。但是該參數(shù)也不會設(shè)置得過大,MapReduce中的map任務通常一次處理一個塊中的數(shù)據(jù),因此如果tasks太少(少于集群中的節(jié)點數(shù)量),job的運行速度就會比較慢。
2.2 namenode和datanode
HDFS集群有兩類節(jié)點,并分別以管理者(nameno?de)、工作者(datanode)模式運行。
namenode管理文件系統(tǒng)的命名空間,它維護著文件系統(tǒng)樹及整棵樹內(nèi)所有的文件和目錄。這些信息以2個文件(命名空間鏡像文件和編輯日志文件)的形式永久保存在本地磁盤上。namenode也記錄著每個文件中各個塊所在的datanode信息,但它并不永久保存塊的位置信息,因為這些信息會在系統(tǒng)啟動時由datanode重建。同時,namenode也負責控制外部Client的訪問。
datanode是文件系統(tǒng)的工作節(jié)點。它們根據(jù)需要存儲并檢索數(shù)據(jù)塊(受客戶端或namenode調(diào)度),響應創(chuàng)建、刪除和復制數(shù)據(jù)塊的命令,并且定期向nameno?de發(fā)送所存儲數(shù)據(jù)塊列表的“心跳”信息。HDFS內(nèi)部的所有通信都基于標準的TCP/IP協(xié)議。namenode獲取每個datanode的心跳信息,namenode據(jù)此驗證塊映射和文件系統(tǒng)元數(shù)據(jù)。
圖2示出的是namenode和datanode。
圖2 namenode和datanode
文件寫入時的步驟為:
a)Client向namenode發(fā)起文件寫入的請求。
b)namenode根據(jù)文件大小和文件塊配置情況,將它管理的datanode節(jié)點的信息返回給Client。
c)Client將文件劃分為多個塊,根據(jù)datanode的地址信息,按順序?qū)懭氲矫恳粋datanode塊中。
文件讀取時的步驟為:
a)Client向namenode發(fā)起文件讀取的請求。
b)namenode返回存儲文件的datanode的信息。
c)Client讀取文件信息。
作為文件系統(tǒng)的管理員,沒有namenode,文件系統(tǒng)將無法使用。如果運行namenode服務的機器毀壞,文件系統(tǒng)上所有的文件將會丟失,且不知道如何根據(jù)datanode的數(shù)據(jù)塊來重建文件。Hadoop為此提供了2種機制對namenode實現(xiàn)冗余備份。
圖3示出的是冗余namenode。
圖3 冗余namenode
一種機制是備份保存文件系統(tǒng)元數(shù)據(jù)的文件。一般配置是:將文件系統(tǒng)元數(shù)據(jù)寫入本地磁盤的同時,寫入一個遠程掛載的網(wǎng)絡文件系統(tǒng)(NFS)。
另一種機制是運行一個輔助的namenode,但它不能被用作namenode。輔助的namenode通過編輯日志定期合并命名空間鏡像。輔助namenode一般在另一臺單獨的物理計算機上運行,因為它需要占用大量CPU時間和與namenode相同容量的內(nèi)存來執(zhí)行合并操作。它會保存合并后的命名空間鏡像的副本,并在namenode發(fā)生故障時啟用。
但是,輔助namenode保存的狀態(tài)總是滯后于主節(jié)點,一般情況融合2種機制。主namenode故障時,把存儲在NFS上的namenode元數(shù)據(jù)復制到輔助namenode上,并將其作為新的主namenode運行。
2.3 命令行接口
HDFS 的文件和目錄有與POSIX 相似的權(quán)限模式,通常是三類權(quán)限模式(rwx)。集群管理員可以通過命令行接口與HDFS交互,執(zhí)行所有常見的文件系統(tǒng)操作,如創(chuàng)建目錄、移動文件、刪除數(shù)據(jù)、列出目錄等等。HDFS并不是一個Unix文件系統(tǒng),不支持像ls和cp這種標準的Unix文件命令。Hadoop提供了一套與Linux文件命令類似的命令行工具,通過shell命令操作文件和目錄。
Hadoop也提供操作HDFS文件和目錄的Java庫,用于以編程方式訪問HDFS。
一般情況下,由MapReduce框架讀取HDFS文件和處理數(shù)據(jù)單元。除非需要定制數(shù)據(jù)的導入和導出,否則幾乎不必編程來讀寫HDFS文件。
3 Hadoop MapReduce淺析
最簡單的MapReduce 應用程序至少包含3 個部分:一個Map 函數(shù)、一個Reduce 函數(shù)和一個main 函數(shù)。main 函數(shù)將作業(yè)控制和文件輸入/輸出結(jié)合起來。在這點上,Hadoop提供了大量的接口和抽象類,從而為Hadoop應用程序開發(fā)人員提供許多工具,可用于調(diào)試和性能度量等。
MapReduce本身就是用于并行處理大數(shù)據(jù)的軟件框架。MapReduce的根源是函數(shù)性編程中的Map函數(shù)和Reduce 函數(shù)。它由2 個可能包含許多事例(許多Map和Reduce)的操作組成。Map函數(shù)接受一組數(shù)據(jù)并將其轉(zhuǎn)換為一個鍵/值對列表,輸入域中的每個元素對應一個鍵/值對。Reduce函數(shù)接受Map函數(shù)生成的列表,然后根據(jù)它們的鍵(為每個鍵生成一個鍵/值對)縮小鍵/值對列表?梢栽诿總域上執(zhí)行Map函數(shù)和Reduce函數(shù),然后將輸出的鍵/值對列表輸入到另一個Reduce函數(shù),就可得到與前面一樣的結(jié)果。換句話說,可以在輸入域并行使用相同的操作,得到的結(jié)果是一樣的,但速度更快。MapReduce的并行功能可在任意數(shù)量的系統(tǒng)上使用。
圖4示出的是MapReduce思想。
3.1 JobTracker和TaskTracker
Hadoop MapReduce 引擎由JobTracker 和Task?Tracker組成。圖5示出的是Hadoop的結(jié)構(gòu)。
JobTracker負責管理調(diào)度所有作業(yè),它是整個系統(tǒng)分配任務的核心。與HDFS的namenode類似,Job?Tracker也是唯一的。它是Hadoop集群中唯一負責控制MapReduce應用程序的系統(tǒng),在應用程序提交之后,將提供包含在HDFS中的輸入和輸出目錄,JobTracker使用文件塊信息(物理量和位置)確定如何創(chuàng)建其他TaskTracker從屬任務,MapReduce應用程序被復制到每個出現(xiàn)文件塊的節(jié)點,為特定節(jié)點上的每個文件塊創(chuàng)建一個唯一的從屬任務。
圖4 MapReduce思想
圖5 Hadoop的結(jié)構(gòu)
TaskTracker具體負責執(zhí)行用戶定義的操作,每個任務被分割為任務集,包含Map任務和Reduce任務。任務是具體執(zhí)行的基本單元,TaskTracker執(zhí)行過程中需要向JobTracker發(fā)送心跳信息,匯報每個任務的執(zhí)行狀態(tài),幫助JobTracker收集作業(yè)執(zhí)行的整體情況,為下次任務的分配提供依據(jù)。
在Hadoop中,Client(任務的提交者)是一組API,用戶需要自定義自己需要的內(nèi)容,由Client將作業(yè)及其配置提交到JobTracker,并監(jiān)控執(zhí)行狀況。
與HDFS的通信機制相同,Hadoop MapReduce也使用協(xié)議接口來實現(xiàn)服務器間的通信。Client與Task?Tracker及TaskTracker之間沒有直接通信。由于集群各主機的通信比較復雜,點對點直接通信難以維持狀態(tài)信息,所以由JobTracker收集整理統(tǒng)一轉(zhuǎn)發(fā)。
3.2 MapReduce的工作機制
JobClient.runJob(conf)這一行簡短的代碼后面隱藏著大量的處理細節(jié)。整個過程如圖6所示,包含如下4個獨立的實體。
圖6 運行MapReduce作業(yè)的工作原理
a)客戶端:提交MapReduce作業(yè)。
b)JobTracker:協(xié)調(diào)作業(yè)的運行。
c)TaskTracker:運行作業(yè)劃分后的任務。
d)分布式文件系統(tǒng)(一般為HDFS):用來在其他實體間共享作業(yè)文件。
3.2.1 作業(yè)的提交
JobClient的runJob()方法是用于新建JobClient實例并調(diào)用其submitJob()方法。提交作業(yè)后,runJob()每秒檢測作業(yè)的進度,如果發(fā)現(xiàn)上次報告后有變化,便把進度報告給控制臺。作業(yè)完成后,如果成功,就顯示作業(yè)計數(shù)器。如果失敗,導致作業(yè)失敗的錯誤被記錄到控制臺。
JobClient的runJob()方法(圖6步驟①)實現(xiàn)過程如下:
a)通過JobTracker的getNewJobId()方法,向Job?Tracker請求一個新的作業(yè)ID(圖6步驟②)。
b)檢查作業(yè)的輸出說明。例如,如果沒有指定輸出目錄或輸出目錄已經(jīng)存在,作業(yè)就不提交,錯誤返回給MapReduce程序。
c)將運行作業(yè)所需要的資源(包括作業(yè)JAR 文件、配置文件和輸入分片)復制到JobTracker文件系統(tǒng)中的一個以作業(yè)ID命名的目錄下(圖6步驟③)。作業(yè)JAR 的副本較多(由mapred.submit.replication 屬性控制,默認值為10), 因此在運行作業(yè)的任務時,集群中有很多個副本可供TaskTracker訪問。
d)通過調(diào)用JobTracker 的submitJob()方法告知JobTracker準備執(zhí)行作業(yè)(圖6步驟④)。
e)計算作業(yè)的輸入分片。如果分片無法計算,例如,因為輸入路徑不存在,作業(yè)就不提交,錯誤返回給MapReduce程序(圖6步驟⑥)。
3.2.2 作業(yè)的初始化
當JobTracker接收到對其submitJob()方法的調(diào)用后,會把此調(diào)用放入一個內(nèi)部隊列中,交由作業(yè)調(diào)度器(job scheduler)進行調(diào)度,并對其進行初始化。初始化包括創(chuàng)建一個表示正在運行作業(yè)的對象——封裝任務和記錄信息,以便跟蹤任務的狀態(tài)和進程(圖6步驟⑤)。
為了創(chuàng)建任務運行列表,作業(yè)調(diào)度器首先從共享文件系統(tǒng)中獲取JobClient已計算好的輸入分片信息(圖6步驟⑥)。然后為每個分片創(chuàng)建一個map任務。創(chuàng)建reduce 任務的數(shù)量由JobConf 的mapred.reduce.task屬性決定,它是用setNumReduceTasks()方法來設(shè)置的,然后調(diào)度器創(chuàng)建相應數(shù)量的要運行的reduce任務。任務在此時被指定ID。
3.2.3 任務的分配
TaskTracker定期向JobTracker發(fā)送心跳。心跳告知JobTracker,TaskTracker是否還存活,同時也充當兩者之間的消息通道。作為心跳的一部分,TaskTracker會指明它是否已經(jīng)準備好運行新的任務。如果是,JobTracker會為它分配一個任務,并使用心跳的返回值與TaskTracker 進行通信(圖6步驟⑦)。
在JobTracker 為TaskTracker 選擇任務之前,JobTracker必須先選定任務所在的作業(yè)。一旦選擇好作業(yè),JobTracker就可以為該作業(yè)選定一個任務。
對于map任務和reduce任務,TaskTracker有固定數(shù)量的任務槽。例如,1個TaskTracker可能同時運行2個map 任務和2 個reduce 任務。準確數(shù)量由TaskTracker內(nèi)核的數(shù)量和內(nèi)存大小來決定。作業(yè)調(diào)度器在處理reduce任務槽之前,會填滿空閑的map任務槽,因此如果TaskTracker至少有一個空閑的map任務槽,JobTracker會先為它選擇一個map任務。
為了選擇一個reduce任務,JobTracker簡單地從待運行的reduce任務列表中選取下一個來執(zhí)行,用不著考慮數(shù)據(jù)的本地化。然而,對于一個map任務,JobTracker會考慮TaskTracker的網(wǎng)絡位置,并選取一個距離其輸入分片文件最近的TaskTracker。
在最理想的情況下,任務是數(shù)據(jù)本地化的(data-local), 也就是任務運行在輸入分片所在的節(jié)點上。同樣,任務也可能是機架本地化的(rack-local)。任務和輸入分片在同一個機架,但不在同一節(jié)點上。一些任務既不是數(shù)據(jù)本地化的,也不是機架本地化的,而是操作另一個機架上的數(shù)據(jù)。
3.2.4 任務的執(zhí)行
現(xiàn)在,TaskTracker已經(jīng)被分配了一個任務,下一步是執(zhí)行該任務。第一步,通過從共享文件系統(tǒng)把作業(yè)的JAR文件復制到TaskTracker所在的文件系統(tǒng),從而實現(xiàn)作業(yè)的JAR文件本地化。同時,TaskTracker將應用程序所需要的全部文件從共享文件系統(tǒng)復制到本地磁盤(圖6步驟⑧)。第二步,TaskTracker為任務新建一個本地工作目錄,并把JAR文件中的內(nèi)容解壓到這個文件夾下。第三步,TaskTracker新建一個TaskRunner實例來運行該任務。
TaskRunner啟動一個新的JVM(圖6步驟⑨)來運行每個任務(圖6步驟⑩), 以便用戶定義的map和re?duce 函數(shù)的任何軟件問題都不會影響到TaskTracker(例如導致其崩坡或掛起等)。任務的子進程每隔幾秒便告知父進程它的進度,直到任務完成。
3.2.5 進度和狀態(tài)的更新
MapReduce作業(yè)是長時間運行的批量作業(yè),這是一個很長的時間段,對于用戶而言,能夠得知作業(yè)進展是很重要的。一個作業(yè)和它的每個任務都有一個狀態(tài)(status), 包括作業(yè)或任務的狀態(tài)(如運行狀態(tài)、成功完成、失敗狀態(tài))、map和reduce的進度、作業(yè)計數(shù)器的值、狀態(tài)信息或描述(可以由用戶代碼來設(shè)置)。
任務在運行時,對其進度保持追蹤。對map任務,任務進度是已處理輸入所占的比例。對reduce任務,情況稍微復雜,但系統(tǒng)仍然會估計已處理reduce輸入的比例。比如,如果reduce任務已經(jīng)執(zhí)行reducer一半的輸入,那么任務的進度便是5/6。因為已經(jīng)完成復制和排序階段(各1/3),并且已經(jīng)完成reduce階段的一半(1/6)。
如果任務報告了進度,便會設(shè)置一個標志以表明狀態(tài)變化將被發(fā)送到TaskTracker。有一個獨立的線程每隔3 s檢查一次此標志,如果已設(shè)置,則告知Task?Tracker當前任務狀態(tài)。同時,TaskTracker每隔5 s發(fā)送心跳到JobTracker(5 s這個間隔是最小值,心跳間隔實際上由集群的大小來決定,更大的集群,間隔會更長一些),并且將TaskTracker運行的所有任務的狀態(tài)發(fā)送至JobTracker。
JobTracker將這些更新狀態(tài)合并起來,生成一個表明所有運行作業(yè)及其所含任務狀態(tài)的全局視圖。同時,JobClient通過查詢JobTracker來獲取最新狀態(tài)?蛻舳艘部梢允褂肑obClient的getJob()方法來得到一個RunningJob的實例,后者包含作業(yè)的所有狀態(tài)信息。
3.2.6 作業(yè)的完成
當JobTracker收到作業(yè)最后一個任務已完成的通知后,便把作業(yè)的狀態(tài)設(shè)置為“成功”。然后,在JobCli?ent查詢狀態(tài)時,便知道任務已經(jīng)完成,于是JobClient打印一條消息告知用戶,然后從runJob()方法返回。最后,JobTracker清空作業(yè)的工作狀態(tài),指示TaskTracker也清空作業(yè)的工作狀態(tài)。
3.3 作業(yè)的調(diào)度
早期版本的Hadoop使用一種非常簡單的方法來調(diào)度用戶的作業(yè)。按照作業(yè)提交的順序,即先進先出(FIFO)調(diào)度算法來運行作業(yè)。典型情況下,每個作業(yè)都會使用整個集群,因此作業(yè)必須等待直到輪到自己運行。雖然共享集群極有可能為多用戶提供大量資源,但問題在于如何公平地在用戶之間分配資源,這需要一個更好的調(diào)度器。
后來版本的Hadoop 加入設(shè)置作業(yè)優(yōu)先級的功能?梢酝ㄟ^設(shè)置mapred.job.priority屬性或JobClient的setJoBPRiority()方法來設(shè)置優(yōu)先級。在這2種方法中,可以選擇VERY_HIGH、HIGH、NORMAL、LOW、VERY_LOW中的一個值作為優(yōu)先級。作業(yè)調(diào)度器會選擇優(yōu)先級最高的那個作業(yè)執(zhí)行。
在Hadoop中,MapReduce的調(diào)度器可以選擇。默認的調(diào)度器是FIFO,還可選擇Fair Scheduler和Capaci?ty Scheduler。
Fair Scheduler的目標是讓每個用戶公平地共享集群能力。如果只有一個作業(yè),它會得到集群的所有資源。隨著提交的作業(yè)越來越多,空閑的TaskTracker任務槽會以“讓每個用戶公平共享集群”這種方式進行分配。即便一個用戶的長時間作業(yè)正在運行而且還在進行過程中,另一個用戶的一個短的作業(yè)會在合理的時間內(nèi)完成。
作業(yè)都被放在作業(yè)池中,在默認情況下,每個用戶都有自己的作業(yè)池。Fair Scheduler支持搶占,如果一個池在特定一段時間內(nèi)未得到公平的資源,它會中止運行池中使用過多資源的任務,以便把任務槽讓給運行資源不足的池。
針對多作業(yè)調(diào)度,Capacity Scheduler調(diào)度方式下,集群由很多隊列組成,每個隊列有一個分配能力。這一點與Fair Scheduler類似,只不過在每個隊列內(nèi)部,作業(yè)根據(jù)FIFO方式調(diào)度。即Capacity Scheduler允許為每個用戶模擬一個獨立的使用FIFO Scheduling的MapReduce集群。
4 應用場景及展望
云計算的偉大之處就在于在進行大數(shù)據(jù)處理時不必再像以往一樣購買大量的服務器集群,租用服務器處理大數(shù)據(jù)更加利于控制成本。Hadoop作為一個重量級的分布式處理開源框架已經(jīng)在大數(shù)據(jù)處理領(lǐng)域有所作為,企業(yè)希望利用Hadoop來規(guī)劃其自身未來數(shù)據(jù)處理的藍圖。從EMC、Oracle到Microsoft,幾乎所有高科技廠商都宣布了自己以Hadoop為基礎(chǔ)的大數(shù)據(jù)戰(zhàn)略。現(xiàn)今Hadoop已經(jīng)成為IT商場吸引客戶的熱點詞匯。
核心關(guān)注:拓步ERP系統(tǒng)平臺是覆蓋了眾多的業(yè)務領(lǐng)域、行業(yè)應用,蘊涵了豐富的ERP管理思想,集成了ERP軟件業(yè)務管理理念,功能涉及供應鏈、成本、制造、CRM、HR等眾多業(yè)務領(lǐng)域的管理,全面涵蓋了企業(yè)關(guān)注ERP管理系統(tǒng)的核心領(lǐng)域,是眾多中小企業(yè)信息化建設(shè)首選的ERP管理軟件信賴品牌。
轉(zhuǎn)載請注明出處:拓步ERP資訊網(wǎng)http://www.ezxoed.cn/
本文標題:Hadoop HDFS和MapReduce 架構(gòu)淺析
本文網(wǎng)址:http://www.ezxoed.cn/html/consultation/1083946768.html