Hadoop之HDFS及NameNode單點故障解決方案

Hadoop之HDFS前端

版權聲明:本文爲yunshuxueyuan原創文章。
如需轉載請標明出處: http://www.cnblogs.com/sxt-zkys/
QQ技術交流羣:299142667
node

HDFS介紹算法

HDFS(Hadoop Distributed File System )Hadoop分佈式文件系統。是根據google發表的論文翻版的。數據庫

什麼是分佈式文件系統服務器

分佈式文件系統(Distributed File System)是指文件系統管理的物理存儲資源不必定直接鏈接在本地節點上,而是經過計算機網絡與節點相連。分佈式文件系統的設計基於客戶機/服務器模式。網絡

[優勢]session

支持超大文件 超大文件在這裏指的是幾百M,幾百GB,甚至幾TB大小的文件。架構

檢測和快速應對硬件故障在集羣的環境中,硬件故障是常見的問題。由於有上千臺服務器鏈接在一塊兒,這樣會致使高故障率。所以故障檢測和自動恢復是hdfs文件系統的一個設計目標運維

流式數據訪問應用程序能以流的形式訪問數據集。主要的是數據的吞吐量,而不是訪問速度。socket

簡化的一致性模型 大部分hdfs操做文件時,須要一次寫入,屢次讀取。在hdfs中,一個文件一旦通過建立、寫入、關閉後,通常就不須要修改了。這樣簡單的一致性模型,有利於提升吞吐量。

[缺點]

低延遲數據訪問如和用戶進行交互的應用,須要數據在毫秒或秒的範圍內獲得響應。因爲hadoop針對高數據吞吐量作了優化,犧牲了獲取數據的延遲,因此對於低延遲來講,不適合用hadoop來作。

大量的小文件Hdfs支持超大的文件,是經過數據分佈在數據節點,數據的元數據保存在名字節點上。名字節點的內存大小,決定了hdfs文件系統可保存的文件數量。雖然如今的系統內存都比較大,但大量的小文件仍是會影響名字節點的性能。

多用戶寫入文件、修改文件Hdfs的文件只能有一次寫入,不支持寫入,也不支持修改。只有這樣數據的吞吐量才能大。

不支持超強的事務沒有像關係型數據庫那樣,對事務有強有力的支持。

 

[HDFS結構]

 

NameNode:分佈式文件系統中的管理者,主要負責管理文件系統的命名空間、集羣配置信息和存儲塊的複製等。NameNode會將文件系統的Meta-data存儲在內存中,這些信息主要包括了文件信息、每個文件對應的文件塊的信息和每個文件塊在DataNode的信息等。

SecondaryNameNode:合併fsimage和fsedits而後再發給namenode。

DataNode:是文件存儲的基本單元,它將Block存儲在本地文件系統中,保存了Block的Meta-data同時週期性地將全部存在的Block信息發送給NameNode。

Client:就是須要獲取分佈式文件系統文件的應用程序。

fsimage:元數據鏡像文件(文件系統的目錄樹。)

edits:元數據的操做日誌(針對文件系統作的修改操做記錄)

NameNode、DataNode和Client之間通訊方式:

client和namenode之間是經過rpc通訊;

datanode和namenode之間是經過rpc通訊;

client和datanode之間是經過簡單的socket通訊。

Client讀取HDFS中數據的流程

1. 客戶端經過調用FileSystem對象的open()方法打開但願讀取的文件。

2. DistributedFileSystem經過使用RPC來調用namenode,以肯定文件起始塊的位置。[注1]

3. Client對輸入流調用read()方法。

4. 存儲着文件起始塊的natanoe地址的DFSInputStream[注2]隨即連接距離最近的datanode。經過對數據流反覆調用read()方法,能夠將數據從datanode傳輸到Client。[注3]

5. 到達快的末端時,DFSInputStream會關閉與該datanode的鏈接,而後尋找下一個快遞最佳datanode。

6. Client讀取數據是按照卡開DFSInputStream與datanode新建鏈接的順序讀取的。它須要詢問namenode來檢索下一批所須要的datanode的位置。一旦完成讀取,調用FSDataInputStream調用close()方法。

[注1]:對於每個塊,namenode返回存在該塊副本的datanode地址。這些datanode根據他們於客戶端的距離來排序,若是客戶端自己就是一個datanode,並保存有響應數據塊的一個副本時,該節點從本地datanode中讀取數據。

[注2]:Di是tribute File System類返回一個FSDataInputStream對象給Client並讀取數據。FSDataInputStream類轉而封裝DFSInputStream對象,該對象管理datanode和namenode的I/O。

[注3]:若是DFSInputStream在與datanode通訊時遇到錯誤,它便會嘗試從這個塊的另一個最臨近datanode讀取數據。它也會記住哪一個故障的natanode,以保證之後不回反覆讀取該節點上後續的塊。DFSInputStream也會經過校驗和確認從datanode發來的數據是否完整。若是發現一個損壞的塊,它就會在DFSinputStream視圖從其餘datanode讀取一個塊的副本以前通知namenode。

Client將數據寫入HDFS流程

1. Client調用DistributedFileSystem對象的create()方法,建立一個文件輸出流

2. DistributedFileSystem對namenode建立一個RPC調用,在文件系統的命名空間中建立一個新文件。

3. Namenode執行各類不一樣的檢查以確保這個文件不存在,而且客戶端有建立該文件的權限。若是這些檢查均經過,namenode就會爲建立新文件記錄一條記錄,不然,文件建立失敗,向Client拋出IOException,DistributedFileSystem向Client返回一個FSDataOutputStream隊形,Client能夠開始寫入數據。

4. DFSOutputStream將它分紅一個個的數據包,並寫入內部隊列。DataStreamer處理數據隊列,它的責任時根據datanode列表來要求namenode分配適合新塊來存儲數據備份。這一組datanode構成一個管線---咱們假設副本數爲3,管路中有3個節點,DataStreamer將數據包流式牀書到管線中第一個datanode,該dananode存儲數據包並將它發送到管線中的第二個datanode,一樣地,第二個datanode存儲該數據包而且發送給管縣中的第3個。

5. DFSOutputStream也維護着一個內部數據包隊列來等待datanode的收到確認回執(ack queue)。當收到管道中全部datanode確認信息後,該數據包纔會從確認隊列刪除。[注1]

6. Client完成數據的寫入後,回對數據流調用close()方法

7. 將剩餘全部的數據包寫入datanode管線中,而且在練習namenode且發送文件寫入完成信號以前。

[注1]:若是在數據寫入期間,datanode發生故障,則:1.關閉管線,確認把隊列中的任何數據包添加回數據隊列的最前端,一去到故障節點下游的datanode不回漏包。2.爲存儲在另外一個正常datanode的當前數據塊指定一個新的標誌,並將給標誌傳給namenode,以便故障datanode在恢復後能夠刪除存儲的部分數據塊。3.從管線中刪除故障數據節點,而且把餘下的數據塊寫入管線中的兩個正常的datanode。namenode注意到副本量不足時,會在另外一個節點上建立一個新的副本。

Hadoop中NameNode單點故障解決方案

Hadoop 1.0內核主要由兩個分支組成:MapReduce和HDFS,這兩個系統的設計缺陷是單點故障,即MR的JobTracker和HDFS的NameNode兩個核心服務均存在單點問題,這裏只討論HDFS的NameNode單點故障的解決方案。

[問題]

HDFS仿照google GFS實現的分佈式存儲系統,由NameNode和DataNode兩種服務組成,其中NameNode是存儲了元數據信息(fsimage)和操做日誌(edits),因爲它是惟一的,其可用性直接決定了整個存儲系統的可用性。由於客戶端對HDFS的讀、寫操做以前都要訪問name node服務器,客戶端只有從name node獲取元數據以後才能繼續進行讀、寫。一旦NameNode出現故障,將影響整個存儲系統的使用。

[解決方案]

Hadoop官方提供了一種quorum journal manager來實現高可用,在高可用配置下,edit log再也不存放在名稱節點,而是存放在一個共享存儲的地方,這個共享存儲由若干Journal Node組成,通常是3個節點(JN小集羣), 每一個JN專門用於存放來自NN的編輯日誌,編輯日誌由活躍狀態的名稱節點寫入。

要有2個NN節點,兩者之中只能有一個處於活躍狀態(active),另外一個是待命狀態(standby),只有active節點才能對外提供讀寫HDFS服務,也只有active態的NN才能向JN寫入編輯日誌;standby的名稱節點只負責從JN小集羣中的JN節點拷貝數據到本地存放。另外,各個DATA NODE也要同時向兩個NameNode節點報告狀態(心跳信息、塊信息)。

 一主一從的2個NameNode節點同時和3個JN構成的組保持通訊,活躍的NameNode節點負責往JN集羣寫入編輯日誌,待命的NN節點負責觀察JN組中的編輯日誌,而且把日誌拉取到待命節點(接管Secondary NameNode的工做)。再加上兩節點各自的fsimage鏡像文件,這樣一來就能確保兩個NN的元數據保持同步。一旦active不可用,standby繼續對外提供服。架構分爲手動模式和自動模式,其中手動模式是指由管理員經過命令進行主備切換,這一般在服務升級時有用,自動模式可下降運維成本,但存在潛在危險。這兩種模式下的架構以下。

[手動模式]

模擬流程:

1. 準備3臺服務器分別用於運行JournalNode進程(也能夠運行在date node服務器上),準備2臺namenode服務器用於運行NameNode進程(兩臺配置 要同樣),DataNode節點數量不限。

2. 分別啓動3臺JN服務器上的JournalNode進程,分別在date node服務器啓動DataNode進程。

3. 須要同步2臺name node之間的元數據。具體作法:從第一臺NN拷貝元數據到放到另外一臺NN,而後啓動第一臺的NameNode進程,再到另外一臺名稱節點上作standby引導。

4. 把第一臺名節點的edit日誌初始化到JN節點,以供standby節點到JN節點拉取數據。

5. 啓動standby狀態的NameNode節點,這樣就能同步fsimage文件。

6. 模擬故障,手動把active狀態的NN故障,轉移到另外一臺NameNode。

[自動模式]

模擬流程:

在手動模式下引入了ZKFC(DFSZKFailoverController)和zookeeper集羣

ZKFC主要負責: 健康監控、session管理、leader選舉

zookeeper集羣主要負責:服務同步

1-6步同手動模式

7. 準備3臺主機安裝zookeeper,3臺主機造成一個小的zookeeper集羣.

8. 啓動ZK集羣每一個節點上的QuorumPeerMain進程

9. 登陸其中一臺NN, 在ZK中初始化HA狀態

10. 模擬故障:停掉活躍的NameNode進程,提早配置的zookeeper會把standby節點自動變爲active,繼續提供服務。

腦裂

腦裂是指在主備切換時,因爲切換不完全或其餘緣由,致使客戶端和Slave誤覺得出現兩個active master,最終使得整個集羣處於混亂狀態。解決腦裂問題,一般採用隔離(Fencing)機制。

共享存儲fencing:確保只有一個Master往共享存儲中寫數據,使用QJM實現fencing。 

Qurom Journal Manager,基於Paxos(基於消息傳遞的一致性算法),Paxos算法是解決分佈式環境中如何就某個值達成一致

[原理]

a. 初始化後,Active把editlog日誌寫到JN上,每一個editlog有一個編號,每次寫editlog只要其中大多數JN返回成功(過半)即認定寫成功。

b.  Standby按期從JN讀取一批editlog,並應用到內存中的FsImage中。

c. NameNode每次寫Editlog都須要傳遞一個編號Epoch給JN,JN會對比Epoch,若是比本身保存的Epoch大或相同,則能夠寫,JN更新本身的Epoch到最新,不然拒絕操做。在切換時,Standby轉換爲Active時,會把Epoch+1,這樣就防止即便以前的NameNode向JN寫日誌,也會失敗。

客戶端fencing:確保只有一個Master能夠響應客戶端的請求。

[原理] 

在RPC層封裝了一層,經過FailoverProxyProvider以重試的方式鏈接NN。經過若干次鏈接一個NN失敗後嘗試鏈接新的NN,對客戶端的影響是重試的時候增長必定的延遲。客戶端能夠設置重試此時和時間

Slave fencing:確保只有一個Master能夠向Slave下發命令。

[原理]

a. 每一個NN改變狀態的時候,向DN發送本身的狀態和一個序列號。

b. DN在運行過程當中維護此序列號,當failover時,新的NN在返回DN心跳時會返回本身的active狀態和一個更大的序列號。DN接收到這個返回是認爲該NN爲新的active。

b. 若是這時原來的active(好比GC)恢復,返回給DN的心跳信息包含active狀態和原來的序列號,這時DN就會拒絕這個NN的命令。

最後在此感謝尚學堂周老師在我學習過程當中給予的幫助。

相關文章
相關標籤/搜索