@[TOC]node
Hadoop由三個模塊組成:分佈式存儲HDFS、分佈式計算MapReduce、資源調度引擎Yarn安全
NameNode負責:文件元數據信息的操做以及處理客戶端的請求
NameNode管理:HDFS文件系統的命名空間NameSpace。
NameNode維護:文件系統樹(FileSystem)以及文件樹中全部的文件和文件夾的元數據信息(matedata)維護文件到塊的對應關係和塊到節點的對應關係
NameNode文件:namespace鏡像文件(fsimage),操做日誌文件(edit log)這些信息被Cache在RAM中,固然這兩個文件也會被持久化存儲在本地硬盤。
NameNode記錄:每一個文件中各個塊所在的數據節點的位置信息。但它並不永久保存塊的位置信息,由於這些信息在系統啓動時由數據節點重建。從數據節點重建:在nameNode啓動時,DataNode向NameNode進行註冊時發送給NameNode服務器
文件名,文件目錄結構,文件屬性(生成時間,副本數,權限)每一個文件的塊列表。
以及列表中的塊與塊所在的DataNode之間的地址映射關係 在內存中加載文件系統中每一個文件和每一個數據塊的引用關係(文件、block、datanode之間的映射信息) 數據會按期保存到本地磁盤,但不保存block的位置信息而是由DataNode註冊時上報和在運行時維護網絡
NameNode負責文件元數據的操做 ,DataNode負責處理文件內容的讀寫請求,數據流不通過NameNode,會詢問它跟那個DataNode聯繫架構
文件數據塊到底存放到哪些DataNode上,是由NameNode決定的,NN根據全局狀況作出放置副本的決定
讀取文件的時候,NN儘可能讓client讀取離它最近的datanode上的副本,下降帶寬消耗和讀取時延app
全權管理數據塊的複製,週期性的接受心跳和塊的狀態報告信息(包含該DataNode上全部數據塊的列表)
若接受到心跳信息,NN認爲DN工做正常,若是在10分鐘後還接受到不到DN的心跳,那麼NN認爲DN已經宕機 這時候NN準備要把DN上的數據塊進行從新的複製。 塊的狀態報告包含了一個DN上全部數據塊的列表,blocks report 每一個1小時發送一次負載均衡
沒有Namenode,HDFS就不能工做。事實上,若是運行namenode的機器壞掉的話,系統中的文件將會徹底丟失,由於沒有其餘方法可以將位於不一樣datanode上的文件塊(blocks)重建文件。所以,namenode的容錯機制很是重要,Hadoop提供了兩種機制。
第一種方式是將持久化存儲在本地硬盤的文件系統元數據備份。Hadoop能夠經過配置來讓Namenode將他的持久化狀態文件寫到不一樣的文件系統中。這種寫操做是同步而且是原子化的。比較常見的配置是在將持久化狀態寫到本地硬盤的同時,也寫入到一個遠程掛載的網絡文件系統(NFS)。
第二種方式是運行一個輔助的Namenode(SecondaryNamenode)。 事實上SecondaryNamenode並不能被用做Namenode它的主要做用是按期的將Namespace鏡像與操做日誌文件(edit log)合併,以防止操做日誌文件(edit log)變得過大。一般,SecondaryNamenode 運行在一個單獨的物理機上,由於合併操做須要佔用大量的CPU時間以及和Namenode至關的內存。輔助Namenode保存着合併後的Namespace鏡像的一個備份,萬一哪天Namenode宕機了,這個備份就能夠用上了。
可是輔助Namenode老是落後於主Namenode,因此在Namenode宕機時,數據丟失是不可避免的。在這種狀況下,通常的,要結合第一種方式中提到的遠程掛載的網絡文件系統(NFS)中的Namenode的元數據文件來使用,把NFS中的Namenode元數據文件,拷貝到輔助Namenode,並把輔助Namenode做爲主Namenode來運行。異步
NameNode的存儲目錄分佈式
一個集羣可能包含上千個DataNode節點,這些DataNode定時和NameNode進行通訊,接受NameNode的指令 爲了減輕NameNode的負擔,NameNode上並不永久保存哪一個DataNode上有哪些數據塊的信息,而是經過DataNode啓動時的上報來更新NameNode上的映射表。
根據客戶端或者是namenode的調度存儲和檢索數據,而且按期向namenode發送所存儲的塊(block)的列表,數據塊在DataNode進程所在的節點上以文件的形式存儲在本地磁盤上 ,一個是數據自己 ,一個是元數據(數據塊的長度,塊數據的校驗和,以及時間戳),維護blockid與DataNode之間的映射信息(元信息)ide
datanode啓動時,每一個datanode對本地磁盤進行掃描,將本datanode上保存的block信息彙報給namenode namenode在接收到的block信息以及該block所在的datanode信息等保存在內存中。
DataNode啓動後向NameNode註冊,經過後週期性(1小時)的向NameNode上報全部的塊信息.
(1)經過向NameNode發送心跳保持與其聯繫(3秒一次),心跳返回結果帶有NN的命令 ,返回的命令爲:如塊的複製,刪除某個數據塊…..
(2)若是10分鐘沒有收到DataNode的心跳,則認爲其已經lost,並copy其上的block到其它DataNode
(3)DN在其文件建立後三週進行驗證其checkSum的值是否和文件建立時的checkSum值一致
集羣中的每一個服務器都運行一個DataNode後臺程序,這個後臺程序負責把HDFS數據塊讀寫到本地的文件系統。 當須要經過客戶端讀/寫某個數據時,先由NameNode告訴客戶端去哪一個DataNode進行具體的讀/寫操做 而後,客戶端直接與這個DataNode服務器上的後臺程序進行通訊,而且對相關的數據塊進行讀/寫操做。
SecondaryNameNode是HDFS架構中的一個組成部分,可是常常因爲名字而被人誤解它真正的用途,其實它真正的用途,是用來保存namenode中對HDFS metadata的信息的備份,並減小namenode重啓的時間。對於hadoop進程中,要配置好並正確的使用snn,仍是須要作一些工做的。hadoop的默認配置中讓snn進程默認運行在了namenode的那臺機器上,可是這樣的話,若是這臺機器出錯,宕機,對恢復HDFS文件系統是很大的災難,更好的方式是:將snn的進程配置在另一臺機器上運行。
在hadoop中,namenode負責對HDFS的metadata的持久化存儲,而且處理來自客戶端的對HDFS的各類操做的交互反饋。爲了保證交互速度,HDFS文件系統的metadata是被load到namenode機器的內存中的,而且會將內存中的這些數據保存到磁盤進行持久化存儲。爲了保證這個持久化過程不會成爲HDFS操做的瓶頸,hadoop採起的方式是:沒有對任何一次的當前文件系統的snapshot進行持久化,對HDFS最近一段時間的操做list會被保存到namenode中的一個叫Editlog的文件中去。當重啓namenode時,除了load fslmage意外,還會對這個Editlog文件中記錄的HDFS操做進行replay,以恢復HDFS重啓以前的最終狀態。
而SecondaryNameNode,會週期性的將Editlog中記錄的對HDFS的操做合併到一個checkpoint中,而後清空Editlog。因此namenode的重啓就會Load最新的一個checkpoint,並重現Editlog中記錄的hdfs操做,因爲Editlog中記錄的是從上一次checkpoint之後到如今的操做列表,因此就會比較小。若是沒有SecondaryNameNode的這個週期性的合併過程,那麼當每次重啓namenode的時候,就會花費很長的時間。而這樣週期性的合併就能減小重啓的時間。同時也能保證HDFS系統的完整性。
這就是SecondaryNameNode所作的事情。因此snn並不能分擔namenode上對HDFS交互性操做的壓力。儘管如此,當namenode機器宕機或者namenode進程出問題時,namenode的daemon進程能夠經過人工的方式從snn上拷貝一份metadata來恢復HDFS文件系統。
至於爲何要將snn進程運行在一臺非NameNode的機器上,這主要出於兩點考慮:
一、可擴展性:建立一個新的HDFS的snapshot(快照)須要將namenode中load到內存的metadata信息所有拷貝一遍,這樣的操做須要的內存和namenode佔用的內存同樣,因爲分配給namenode進程的內存實際上是對HDFS文件系統的限制,若是分佈式文件系統很是的大,那麼namenode那臺機器的內存就可能會被namenode進程所有佔據。
二、容錯性:當snn建立一個checkpoint的時候,它會將checkpoint拷貝成metadata的幾個拷貝。將這個操做運行到另一臺機器,還能夠提供分佈式文件系統的容錯性。
SECONDARYNAMENODE工做原理
日誌與鏡像的按期合併總共分五步:
一、SecondaryNameNode通知NameNode準備提交edits文件,此時主節點產生edits.new
二、SecondaryNameNode經過http get方式獲取NameNode的fsimage與edits文件(在SecondaryNameNode的current同級目錄下可見到 temp.check-point或者previous-checkpoint目錄,這些目錄中存儲着從namenode拷貝來的鏡像文件)
三、SecondaryNameNode開始合併獲取的上述兩個文件,產生一個新的fsimage文件fsimage.ckpt
四、SecondaryNameNode用http post方式發送fsimage.ckpt至NameNode
五、NameNode將fsimage.ckpt與edits.new文件分別重命名爲fsimage與edits,而後更新fstime,整個checkpoint過程到此結束。 在新版本的hadoop中(hadoop0.21.0),SecondaryNameNode兩個做用被兩個節點替換, checkpoint node與backup node. SecondaryNameNode備份由三個參數控制fs.checkpoint.period控制週期,fs.checkpoint.size控制日誌文件超過多少大小時合併, dfs.http.address表示http地址,這個參數在SecondaryNameNode爲單獨節點時須要設置。
工做原理:
Hadoop的HDFS集羣很是容易出現機器與機器之間磁盤利用率不平衡的狀況,例如:當集羣內新增、刪除節點,或者某個節點機器內硬盤存儲達到飽和值。當數據不平衡時,Map任務可能會分配到沒有存儲數據的機器,這將致使網絡帶寬的消耗,也沒法很好的進行本地計算。
當HDFS負載不均衡時,須要對HDFS進行數據的負載均衡調整,即對各節點機器上數據的存儲分佈進行調整。從而,讓數據均勻的分佈在各個DataNode上,均衡IO性能,防止熱點的發生。進行數據的負載均衡調整,必需要知足以下原則:
c(1)數據平衡不能致使數據塊減小,數據塊備份丟失
(2)管理員能夠停止數據平衡進程
(3)每次移動的數據量以及佔用的網絡資源,必須是可控的
(4)數據均衡過程,不能影響namenode的正常工做
負載均衡原理以下:
步驟分析以下:
(1)數據均衡服務(Rebalancing Server)首先要求 NameNode 生成 DataNode 數據分佈分析報告,獲取每一個DataNode磁盤使用狀況
(2)Rebalancing Server彙總須要移動的數據分佈狀況,計算具體數據塊遷移路線圖。數據塊遷移路線圖,確保網絡內最短路徑
(3)開始數據塊遷移任務,Proxy Source Data Node複製一塊須要移動數據塊
(4)將複製的數據塊複製到目標DataNode上
(5)刪除原始數據塊
(6)目標DataNode向Proxy Source Data Node確認該數據塊遷移完成
(7)Proxy Source Data Node向Rebalancing Server確認本次數據塊遷移完成。而後繼續執行這個過程,直至集羣達到數據均衡標準
在瞭解讀寫過程以前先了瞭解基本的概念:
在DFSClient寫HDFS的過程當中,有三個須要搞清楚的單位:block、packet與chunk;
block是最大的一個單位,它是最終存儲於DataNode上的數據粒度,由dfs.block.size參數決定,默認是64M;注:這個參數由客戶端配置決定;
packet是中等的一個單位,它是數據由DFSClient流向DataNode的粒度,以dfs.write.packet.size參數爲參考值,默認是64K;注:這個參數爲參考值,是指真正在進行數據傳輸時,會以它爲基準進行調整,調整的緣由是一個packet有特定的結構,調整的目標是這個packet的大小恰好包含結構中的全部成員,同時也保證寫到DataNode後當前block的大小不超過設定值;
chunk是最小的一個單位,它是DFSClient到DataNode數據傳輸中進行數據校驗的粒度,由io.bytes.per.checksum參數決定,默認是512B;
注:事實上一個chunk還包含4B的校驗值,於是chunk寫入packet時是516B;數據與檢驗值的比值爲128:1,因此對於一個128M的block會有一個1M的校驗文件與之對應;
一、客戶端調用FileSystem 實例的open 方法,得到這個文件對應的輸入流InputStream。
二、經過RPC 遠程調用NameNode ,得到NameNode 中此文件對應的數據塊保存位置,包括這個文件的副本的保存位置( 主要是各DataNode的地址) 。
三、得到輸入流以後,客戶端調用read 方法讀取數據。選擇最近的DataNode 創建鏈接並讀取數據。
四、若是客戶端和其中一個DataNode 位於同一機器(好比MapReduce 過程當中的mapper 和reducer),那麼就會直接從本地讀取數據。
五、到達數據塊末端,關閉與這個DataNode 的鏈接,而後從新查找下一個數據塊。
六、不斷執行第2 - 5 步直到數據所有讀完。
七、客戶端調用close ,關閉輸入流DF S InputStream。
在讀的過程當中如何保證數據的完整性:
經過校驗和。由於每一個chunk中都有一個校驗位,一個個chunk構成packet,一個個packet最終造成block,故可在block上求校驗和。HDFS 的client端即實現了對 HDFS 文件內容的校驗和 (checksum) 檢查。當客戶端建立一個新的HDFS文件時候,分塊後會計算這個文件每一個數據塊的校驗和,此校驗和會以一個隱藏文件形式保存在同一個 HDFS 命名空間下。當client端從HDFS中讀取文件內容後,它會檢查分塊時候計算出的校驗和(隱藏文件裏)和讀取到的文件塊中校驗和是否匹配,若是不匹配,客戶端能夠選擇從其餘 Datanode 獲取該數據塊的副本。
一、使用 HDFS 提供的客戶端 Client,向遠程的 namenode 發起 RPC 請求 二、namenode 會檢查要建立的文件是否已經存在,建立者是否有權限進行操做,成功則會 爲文件建立一個記錄,不然會讓客戶端拋出異常; 三、當客戶端開始寫入文件的時候,客戶端會將文件切分紅多個 packets,並在內部以數據隊列「data queue(數據隊列)」的形式管理這些 packets,並向 namenode 申請 blocks,獲 取用來存儲 replicas 的合適的 datanode 列表,列表的大小根據 namenode 中 replication 的設定而定; 四、開始以 pipeline(管道)的形式將 packet 寫入全部的 replicas 中。客戶端把 packet 以流的 方式寫入第一個 datanode,該 datanode 把該 packet 存儲以後,再將其傳遞給在此 pipeline 中的下一個 datanode,直到最後一個 datanode,這種寫數據的方式呈流水線的形式。 五、最後一個 datanode 成功存儲以後會返回一個 ack packet(確認隊列),在 pipeline 裏傳遞 至客戶端,在客戶端的開發庫內部維護着"ack queue",成功收到 datanode 返回的 ack packet 後會從"data queue"移除相應的 packet。 六、若是傳輸過程當中,有某個 datanode 出現了故障,那麼當前的 pipeline 會被關閉,出現故 障的 datanode 會從當前的 pipeline 中移除,剩餘的 block 會繼續剩下的 datanode 中繼續 以 pipeline 的形式傳輸,同時 namenode 會分配一個新的 datanode,保持 replicas 設定的 數量。 七、客戶端完成數據的寫入後,會對數據流調用 close()方法,關閉數據流; 八、只要寫入了 dfs.replication.min(最小寫入成功的副本數)的複本數(默認爲 1),寫操做 就會成功,而且這個塊能夠在集羣中異步複製,直到達到其目標複本數(dfs.replication 的默認值爲 3),由於 namenode 已經知道文件由哪些塊組成,因此它在返回成功前只需 要等待數據塊進行最小量的複製。