Hadoop由三個模塊組成:分布式存儲HDFS、分布式計算MapReduce、資源調(diào)度引擎Yarn
??? NameNode負責:文件元數(shù)據(jù)信息的操作以及處理客戶端的請求
???NameNode管理:HDFS文件系統(tǒng)的命名空間NameSpace。
???NameNode維護:文件系統(tǒng)樹(FileSystem)以及文件樹中所有的文件和文件夾的元數(shù)據(jù)信息(matedata)維護文件到塊的對應(yīng)關(guān)系和塊到節(jié)點的對應(yīng)關(guān)系
???NameNode文件:namespace鏡像文件(fsimage),操作日志文件(edit log)這些信息被Cache在RAM中,當然這兩個文件也會被持久化存儲在本地硬盤。
???NameNode記錄:每個文件中各個塊所在的數(shù)據(jù)節(jié)點的位置信息。但它并不永久保存塊的位置信息,因為這些信息在系統(tǒng)啟動時由數(shù)據(jù)節(jié)點重建。從數(shù)據(jù)節(jié)點重建:在nameNode啟動時,DataNode向NameNode進行注冊時發(fā)送給NameNode
???文件名,文件目錄結(jié)構(gòu),文件屬性(生成時間,副本數(shù),權(quán)限)每個文件的塊列表。以及列表中的塊與塊所在的DataNode之間的地址映射關(guān)系 在內(nèi)存中加載文件系統(tǒng)中每個文件和每個數(shù)據(jù)塊的引用關(guān)系(文件、block、datanode之間的映射信息) 數(shù)據(jù)會定期保存到本地磁盤,但不保存block的位置信息而是由DataNode注冊時上報和在運行時維護
NameNode負責文件元數(shù)據(jù)的操作 ,DataNode負責處理文件內(nèi)容的讀寫請求,數(shù)據(jù)流不經(jīng)過NameNode,會詢問它跟那個DataNode聯(lián)系
文件數(shù)據(jù)塊到底存放到哪些DataNode上,是由NameNode決定的,NN根據(jù)全局情況做出放置副本的決定讀取文件的時候,NN盡量讓client讀取離它最近的datanode上的副本,降低帶寬消耗和讀取時延
全權(quán)管理數(shù)據(jù)塊的復制,周期性的接受心跳和塊的狀態(tài)報告信息(包含該DataNode上所有數(shù)據(jù)塊的列表)
若接受到心跳信息,NN認為DN工作正常,如果在10分鐘后還接受到不到DN的心跳,那么NN認為DN已經(jīng)宕機 這時候NN準備要把DN上的數(shù)據(jù)塊進行重新的復制。 塊的狀態(tài)報告包含了一個DN上所有數(shù)據(jù)塊的列表,blocks report 每個1小時發(fā)送一次
???? 沒有Namenode,HDFS就不能工作。事實上,如果運行namenode的機器壞掉的話,系統(tǒng)中的文件將會完全丟失,因為沒有其他方法能夠?qū)⑽挥诓煌琩atanode上的文件塊(blocks)重建文件。因此,namenode的容錯機制非常重要,Hadoop提供了兩種機制。
????第一種方式是將持久化存儲在本地硬盤的文件系統(tǒng)元數(shù)據(jù)備份。Hadoop可以通過配置來讓Namenode將他的持久化狀態(tài)文件寫到不同的文件系統(tǒng)中。這種寫操作是同步并且是原子化的。比較常見的配置是在將持久化狀態(tài)寫到本地硬盤的同時,也寫入到一個遠程掛載的網(wǎng)絡(luò)文件系統(tǒng)(NFS)。
????第二種方式是運行一個輔助的Namenode(SecondaryNamenode)。 事實上SecondaryNamenode并不能被用作Namenode它的主要作用是定期的將Namespace鏡像與操作日志文件(edit log)合并,以防止操作日志文件(edit log)變得過大。通常,SecondaryNamenode 運行在一個單獨的物理機上,因為合并操作需要占用大量的CPU時間以及和Namenode相當?shù)膬?nèi)存。輔助Namenode保存著合并后的Namespace鏡像的一個備份,萬一哪天Namenode宕機了,這個備份就可以用上了。
????但是輔助Namenode總是落后于主Namenode,所以在Namenode宕機時,數(shù)據(jù)丟失是不可避免的。在這種情況下,一般的,要結(jié)合第一種方式中提到的遠程掛載的網(wǎng)絡(luò)文件系統(tǒng)(NFS)中的Namenode的元數(shù)據(jù)文件來使用,把NFS中的Namenode元數(shù)據(jù)文件,拷貝到輔助Namenode,并把輔助Namenode作為主Namenode來運行。
???? 一個集群可能包含上千個DataNode節(jié)點,這些DataNode定時和NameNode進行通信,接受NameNode的指令 為了減輕NameNode的負擔,NameNode上并不永久保存哪個DataNode上有哪些數(shù)據(jù)塊的信息,而是通過DataNode啟動時的上報來更新NameNode上的映射表。
????根據(jù)客戶端或者是namenode的調(diào)度存儲和檢索數(shù)據(jù),并且定期向namenode發(fā)送所存儲的塊(block)的列表,數(shù)據(jù)塊在DataNode進程所在的節(jié)點上以文件的形式存儲在本地磁盤上 ,一個是數(shù)據(jù)本身 ,一個是元數(shù)據(jù)(數(shù)據(jù)塊的長度,塊數(shù)據(jù)的校驗和,以及時間戳),維護blockid與DataNode之間的映射信息(元信息)
????datanode啟動時,每個datanode對本地磁盤進行掃描,將本datanode上保存的block信息匯報給namenode namenode在接收到的block信息以及該block所在的datanode信息等保存在內(nèi)存中。
DataNode啟動后向NameNode注冊,通過后周期性(1小時)的向NameNode上報所有的塊信息.
????(1)通過向NameNode發(fā)送心跳保持與其聯(lián)系(3秒一次),心跳返回結(jié)果帶有NN的命令 ,返回的命令為:如塊的復制,刪除某個數(shù)據(jù)塊……
????(2)如果10分鐘沒有收到DataNode的心跳,則認為其已經(jīng)lost,并copy其上的block到其它DataNode
????(3)DN在其文件創(chuàng)建后三周進行驗證其checkSum的值是否和文件創(chuàng)建時的checkSum值一致
????集群中的每個服務(wù)器都運行一個DataNode后臺程序,這個后臺程序負責把HDFS數(shù)據(jù)塊讀寫到本地的文件系統(tǒng)。 當需要通過客戶端讀/寫某個數(shù)據(jù)時,先由NameNode告訴客戶端去哪個DataNode進行具體的讀/寫操作 然后,客戶端直接與這個DataNode服務(wù)器上的后臺程序進行通信,并且對相關(guān)的數(shù)據(jù)塊進行讀/寫操作。
????SecondaryNameNode是HDFS架構(gòu)中的一個組成部分,但是經(jīng)常由于名字而被人誤解它真正的用途,其實它真正的用途,是用來保存namenode中對HDFS metadata的信息的備份,并減少namenode重啟的時間。對于hadoop進程中,要配置好并正確的使用snn,還是需要做一些工作的。hadoop的默認配置中讓snn進程默認運行在了namenode的那臺機器上,但是這樣的話,如果這臺機器出錯,宕機,對恢復HDFS文件系統(tǒng)是很大的災(zāi)難,更好的方式是:將snn的進程配置在另外一臺機器上運行。
????在hadoop中,namenode負責對HDFS的metadata的持久化存儲,并且處理來自客戶端的對HDFS的各種操作的交互反饋。為了保證交互速度,HDFS文件系統(tǒng)的metadata是被load到namenode機器的內(nèi)存中的,并且會將內(nèi)存中的這些數(shù)據(jù)保存到磁盤進行持久化存儲。為了保證這個持久化過程不會成為HDFS操作的瓶頸,hadoop采取的方式是:沒有對任何一次的當前文件系統(tǒng)的snapshot進行持久化,對HDFS最近一段時間的操作list會被保存到namenode中的一個叫Editlog的文件中去。當重啟namenode時,除了load fslmage意外,還會對這個Editlog文件中記錄的HDFS操作進行replay,以恢復HDFS重啟之前的最終狀態(tài)。
????而SecondaryNameNode,會周期性的將Editlog中記錄的對HDFS的操作合并到一個checkpoint中,然后清空Editlog。所以namenode的重啟就會Load最新的一個checkpoint,并重現(xiàn)Editlog中記錄的hdfs操作,由于Editlog中記錄的是從上一次checkpoint以后到現(xiàn)在的操作列表,所以就會比較小。如果沒有SecondaryNameNode的這個周期性的合并過程,那么當每次重啟namenode的時候,就會花費很長的時間。而這樣周期性的合并就能減少重啟的時間。同時也能保證HDFS系統(tǒng)的完整性。
????這就是SecondaryNameNode所做的事情。所以snn并不能分擔namenode上對HDFS交互性操作的壓力。盡管如此,當namenode機器宕機或者namenode進程出問題時,namenode的daemon進程可以通過人工的方式從snn上拷貝一份metadata來恢復HDFS文件系統(tǒng)。
至于為什么要將snn進程運行在一臺非NameNode的機器上,這主要出于兩點考慮:
????1、可擴展性:創(chuàng)建一個新的HDFS的snapshot(快照)需要將namenode中l(wèi)oad到內(nèi)存的metadata信息全部拷貝一遍,這樣的操作需要的內(nèi)存和namenode占用的內(nèi)存一樣,由于分配給namenode進程的內(nèi)存其實是對HDFS文件系統(tǒng)的限制,如果分布式文件系統(tǒng)非常的大,那么namenode那臺機器的內(nèi)存就可能會被namenode進程全部占據(jù)。
????2、容錯性:當snn創(chuàng)建一個checkpoint的時候,它會將checkpoint拷貝成metadata的幾個拷貝。將這個操作運行到另外一臺機器,還可以提供分布式文件系統(tǒng)的容錯性。
SECONDARYNAMENODE工作原理
日志與鏡像的定期合并總共分五步:
????1、SecondaryNameNode通知NameNode準備提交edits文件,此時主節(jié)點產(chǎn)生edits.new
????2、SecondaryNameNode通過http get方式獲取NameNode的fsimage與edits文件(在SecondaryNameNode的current同級目錄下可見到 temp.check-point或者previous-checkpoint目錄,這些目錄中存儲著從namenode拷貝來的鏡像文件)
????3、SecondaryNameNode開始合并獲取的上述兩個文件,產(chǎn)生一個新的fsimage文件fsimage.ckpt
????4、SecondaryNameNode用http post方式發(fā)送fsimage.ckpt至NameNode
????5、NameNode將fsimage.ckpt與edits.new文件分別重命名為fsimage與edits,然后更新fstime,整個checkpoint過程到此結(jié)束。 在新版本的hadoop中(hadoop0.21.0),SecondaryNameNode兩個作用被兩個節(jié)點替換, checkpoint node與backup node. SecondaryNameNode備份由三個參數(shù)控制fs.checkpoint.period控制周期,fs.checkpoint.size控制日志文件超過多少大小時合并, dfs.http.address表示http地址,這個參數(shù)在SecondaryNameNode為單獨節(jié)點時需要設(shè)置。
工作原理:
????Hadoop的HDFS集群非常容易出現(xiàn)機器與機器之間磁盤利用率不平衡的情況,例如:當集群內(nèi)新增、刪除節(jié)點,或者某個節(jié)點機器內(nèi)硬盤存儲達到飽和值。當數(shù)據(jù)不平衡時,Map任務(wù)可能會分配到?jīng)]有存儲數(shù)據(jù)的機器,這將導致網(wǎng)絡(luò)帶寬的消耗,也無法很好的進行本地計算。
當HDFS負載不均衡時,需要對HDFS進行數(shù)據(jù)的負載均衡調(diào)整,即對各節(jié)點機器上數(shù)據(jù)的存儲分布進行調(diào)整。從而,讓數(shù)據(jù)均勻的分布在各個DataNode上,均衡IO性能,防止熱點的發(fā)生。進行數(shù)據(jù)的負載均衡調(diào)整,必須要滿足如下原則:
c(1)數(shù)據(jù)平衡不能導致數(shù)據(jù)塊減少,數(shù)據(jù)塊備份丟失
????(2)管理員可以中止數(shù)據(jù)平衡進程
????(3)每次移動的數(shù)據(jù)量以及占用的網(wǎng)絡(luò)資源,必須是可控的
????(4)數(shù)據(jù)均衡過程,不能影響namenode的正常工作
負載均衡原理如下:
????在了解讀寫過程之前先了了解基本的概念:
????在DFSClient寫HDFS的過程中,有三個需要搞清楚的單位:block、packet與chunk;
????block是最大的一個單位,它是最終存儲于DataNode上的數(shù)據(jù)粒度,由dfs.block.size參數(shù)決定,默認是64M;注:這個參數(shù)由客戶端配置決定;
????packet是中等的一個單位,它是數(shù)據(jù)由DFSClient流向DataNode的粒度,以dfs.write.packet.size參數(shù)為參考值,默認是64K;注:這個參數(shù)為參考值,是指真正在進行數(shù)據(jù)傳輸時,會以它為基準進行調(diào)整,調(diào)整的原因是一個packet有特定的結(jié)構(gòu),調(diào)整的目標是這個packet的大小剛好包含結(jié)構(gòu)中的所有成員,同時也保證寫到DataNode后當前block的大小不超過設(shè)定值;
????chunk是最小的一個單位,它是DFSClient到DataNode數(shù)據(jù)傳輸中進行數(shù)據(jù)校驗的粒度,由io.bytes.per.checksum參數(shù)決定,默認是512B;
????注:事實上一個chunk還包含4B的校驗值,因而chunk寫入packet時是516B;數(shù)據(jù)與檢驗值的比值為128:1,所以對于一個128M的block會有一個1M的校驗文件與之對應(yīng);