本文將從NameNode,DataNode,SecondaryNameNode,心跳檢測(cè),負(fù)載均衡五個(gè)方面展開討論HDFS架構(gòu)。
HDFS整體架構(gòu)
首先上一張簡(jiǎn)單的架構(gòu)圖:
其中:
- 大多數(shù)分布式大數(shù)據(jù)框架都是主從架構(gòu)。
- HDFS也是主從架構(gòu)(其中,Master稱為管理節(jié)點(diǎn),Slave稱為工作節(jié)點(diǎn))
- 主叫NameNode,中文名稱為"名稱節(jié)點(diǎn)"。
- 從叫DataNode,中文名稱為"數(shù)據(jù)節(jié)點(diǎn)"。
NameNode
文件系統(tǒng)
先談?wù)勎募到y(tǒng)概念。
- 文件系統(tǒng)(filesystem)概念:操作系統(tǒng)中負(fù)責(zé)管理文件,存儲(chǔ)文件信息的軟件。具體地說(shuō),它負(fù)責(zé)為用戶創(chuàng)建文件,存入,讀取,修改,轉(zhuǎn)儲(chǔ),刪除文件等。
再說(shuō)說(shuō)與文件系統(tǒng)有關(guān)的幾個(gè)概念。
-
元數(shù)據(jù)(metadata):關(guān)于用戶或目錄的描述信息,如文件所在路徑,文件名稱,文件類型等等,這些信息被稱為文件的元數(shù)據(jù)信息。如:
metadata.png
注意:元數(shù)據(jù)的概念在其它的的數(shù)據(jù)框架中也屢有提及。
- 命名空間
- 文件系統(tǒng)中,為了便于管理存儲(chǔ)介質(zhì)上的,給每個(gè)目錄、目錄中的文件、子目錄都起了名字,這樣形成的層級(jí)結(jié)構(gòu),稱之為命名空間。
- 同一目錄中,不能有同名的文件或目錄。
- 用處:這樣通過(guò)目錄+文件名稱的方式能夠唯一的定位一個(gè)文件。
HDFS-NameNode
- HDFS本質(zhì)上也是文件系統(tǒng)filesystem,所以它也有元數(shù)據(jù)metadata;
- 元數(shù)據(jù)metadata保存在NameNode內(nèi)存中;
- NameNode作用
- HDFS的主節(jié)點(diǎn),負(fù)責(zé)管理文件系統(tǒng)的命名空間,將HDFS的元數(shù)據(jù)存儲(chǔ)在NameNode節(jié)點(diǎn)的內(nèi)存中。
- 負(fù)責(zé)響應(yīng)客戶端對(duì)文件的讀寫請(qǐng)求。
- HDFS元數(shù)據(jù)
-
文件目錄樹、所有的文件(目錄)名稱、文件屬性(生成時(shí)間、副本、權(quán)限)、每個(gè)文 件的塊列表、每個(gè)block塊所在的datanode列表。
metadata.png - 每個(gè)文件,目錄,block占用大概150Bytes字節(jié)的元數(shù)據(jù);所以HDFS適合存儲(chǔ)大文件,不適合存儲(chǔ)小文件(1000個(gè)1M的文件和1000個(gè)150M的文件所占用的元數(shù)據(jù)內(nèi)存是一樣多的,但是后者在hdfs上存儲(chǔ)的文件更多)。
-
HDFS元數(shù)據(jù)信息以兩種形式保存:編輯日志(edits log)和命名空間鏡像文件(fsimage)
(1). edits log:HDFS編輯日志文件 ,保存客戶端對(duì)HDFS的所有更改記錄,如增、刪、重命名文件(目錄),這些操作會(huì)修改HDFS目錄樹;NameNode會(huì)在編輯日志edit日志中記錄下來(lái);(類似于MySQL中的binlog)
(2). fsimage:HDFS元數(shù)據(jù)鏡像文件 ,即將namenode內(nèi)存中的數(shù)據(jù)落入磁盤生成的文件;保存了文件系統(tǒng)目錄樹信息以及文件、塊、datanode的映射關(guān)系,如下圖:
edits && fsimage.png
-
- hdfs-site.xml中屬性dfs.namenode.edits.dir的值決定;用于namenode保存edits log文件。
- hdfs-site.xml中屬性dfs.namenode.name.dir的值決定;用于namenode保存fsimage文件。
DataNode
DataNode數(shù)據(jù)節(jié)點(diǎn)的作用比較簡(jiǎn)單,主要是存儲(chǔ)block元數(shù)據(jù)到datanode本地磁盤;此處的元數(shù)據(jù)包括數(shù)據(jù)塊的長(zhǎng)度,塊數(shù)據(jù)的校驗(yàn)和,時(shí)間戳。
SecondaryNameNode
在解釋SecondaryNameNode之前,先看看如下2個(gè)問(wèn)題。
- 為什么元數(shù)據(jù)存儲(chǔ)在NameNode的內(nèi)存中?
答:當(dāng)HDFS Client需要讀寫文件時(shí),首先HDFS Client連接到NameNode,獲取文件的元數(shù)據(jù)信息,知道了當(dāng)前想要訪問(wèn)的文件的block分別存放在哪些DataNode節(jié)點(diǎn)上,然后HDFS Client分別連接這些DataNode,然后讀寫文件。當(dāng)HDFS Client很多的時(shí)候,如果將元數(shù)據(jù)存儲(chǔ)在磁盤上的話,這些Client想要訪問(wèn)這些元數(shù)據(jù)信息就會(huì)特別慢,但是如果將元數(shù)據(jù)保存在內(nèi)存中就不一樣了。 - 這樣做有什么問(wèn)題?如何解決?
答:這樣的問(wèn)題是:一旦NameNode節(jié)點(diǎn)系統(tǒng)故障,會(huì)導(dǎo)致保存在NameNode節(jié)點(diǎn)內(nèi)存中的元數(shù)據(jù)丟失。解決方式:edits log已經(jīng)記錄了客戶端對(duì)HDFS的所有的更改的操作記錄(如增,刪,改,重命名文件或者目錄)。如果系統(tǒng)故障,重啟之后,可以從edits log進(jìn)行恢復(fù)(edits log回放這些操作記錄)。但edits log日志大小隨著時(shí)間變得越來(lái)越大,導(dǎo)致系統(tǒng)重啟根據(jù)日志恢復(fù)的時(shí)候會(huì)變得越來(lái)越長(zhǎng);為了避免這種情況,引入檢查點(diǎn)機(jī)制checkpoint,命名空間鏡像fsimage就是根據(jù)HDFS數(shù)據(jù)的持久性檢查點(diǎn),即將內(nèi)存中的元數(shù)據(jù)落地磁盤生成的文件。NameNode如果重啟,可以將磁盤中的fsimage文件讀入到內(nèi)存,將元數(shù)據(jù)恢復(fù)到某一個(gè)檢查點(diǎn),然后再回放檢查點(diǎn)之后記錄的編輯日志,最后完全恢復(fù)元數(shù)據(jù)。但是依然,隨著時(shí)間的推移,edits log記錄的日志會(huì)變多,那么當(dāng)NameNode重啟,恢復(fù)元數(shù)據(jù)過(guò)程中,會(huì)花越來(lái)越長(zhǎng)的時(shí)間執(zhí)行edits log中的每一個(gè)日志;而在NameNode元數(shù)據(jù)恢復(fù)期間,HDFS不可用。
為了解決這個(gè)問(wèn)題,引入了SecondaryNameNode輔助NameNode,用來(lái)合并fsimage和edits log。
-
SecondaryNameNode合并fsimage和edits log詳細(xì)流程如下:
- SecondaryNameNode首先請(qǐng)求原NameNode進(jìn)行edits的滾動(dòng),這樣新的編輯操作就能夠進(jìn)入新的文件中。
- SecondaryNameNode通過(guò)HTTP GET方式讀取原NameNode中的fsimage及edits log。
- SecondaryNameNode讀取fsimage到內(nèi)存中,然后回放edits log中的每個(gè)操作,并創(chuàng)建一個(gè)新的統(tǒng)一的fsimage文件。
- SecondaryNameNode通過(guò)HTTP PUT方式將新的fsimage發(fā)送到原NameNode。
- 原NameNode用新的fsimage替換舊的fsimage,同時(shí)系統(tǒng)會(huì)更新fsimage文件到記錄檢查點(diǎn)的時(shí)間。
- 這個(gè)過(guò)程結(jié)束后,NameNode就有了最新的fsimage文件和更小的edits log文件。
-
SecondaryNameNode定期做checkpoint檢查點(diǎn)操作的兩大條件:
- SecondaryNameNode每隔1小時(shí)創(chuàng)建一個(gè)檢查點(diǎn)
- 另外,SecondaryNameNode每1分鐘檢查一次,從上一檢查點(diǎn)開始,edits log文件中是否已包括100萬(wàn)個(gè)事務(wù),如果是,也會(huì)創(chuàng)建檢查點(diǎn)。
SecondaryNameNode一般部署在另外一臺(tái)節(jié)點(diǎn)上,因?yàn)樗枰加么罅康腃PU時(shí)間,并需要和NameNode一樣多的內(nèi)存,來(lái)執(zhí)行合并操作。
- 查看edits log和fsimage
hdfs oev -i edits_0000000000000000256-0000000000000000363 -o /home/hadoop/edit1.xml
hdfs oiv -p XML -i fsimage_0000000000000092691 -o fsimage.xml
執(zhí)行以上兩個(gè)命令后,會(huì)將二進(jìn)制格式的edits log和fsimage轉(zhuǎn)化為xml文件。
- checkpoint相關(guān)屬性(參考hadoop官方文檔)
屬性 | 值 | 解釋 |
---|---|---|
dfs.namenode.checkpoint.period | 3600秒(即1小時(shí)) | The number of seconds between two periodic checkpoints. |
dfs.namenode.checkpoint.txns | 1000000 | The Secondary NameNode or CheckpointNode will create a checkpoint of the namespace every 'dfs.namenode.checkpoint.txns' transactions, regardless of whether 'dfs.namenode.checkpoint.period' has expired. |
dfs.namenode.checkpoint.check.period | 60(1分鐘) | The SecondaryNameNode and CheckpointNode will poll the NameNode every 'dfs.namenode.checkpoint.check.period' seconds to query the number of uncheckpointed transactions. |
心跳機(jī)制
工作原理
- NameNode啟動(dòng)的時(shí)候,會(huì)開一個(gè)ipc server在那里
- DataNode啟動(dòng)后向NameNode注冊(cè),每隔3秒鐘向NameNode發(fā)送一個(gè)"心跳heartbeat"
- 心跳返回結(jié)果帶有NameNode給該DataNode的命令,如復(fù)制塊數(shù)據(jù)到另一DataNode,或刪除某個(gè)數(shù)據(jù)塊
- 如果超過(guò)10分鐘NameNode沒(méi)有收到某個(gè)DataNode 的心跳,則認(rèn)為該DataNode節(jié)點(diǎn)不可用
- DataNode周期性(6小時(shí))的向NameNode上報(bào)當(dāng)前DataNode上的塊狀態(tài)報(bào)告BlockReport;塊狀態(tài)報(bào)告包含了一個(gè)該 Datanode上所有數(shù)據(jù)塊的列表。
心跳的作用
- 通過(guò)周期心跳,NameNode可以向DataNode返回指令
- 可以判斷DataNode是否在線
- 通過(guò)BlockReport,NameNode能夠知道各DataNode的存儲(chǔ)情況,如磁盤利用率、塊列表;跟負(fù)載均衡有關(guān)
- hadoop集群剛開始啟動(dòng)時(shí),99.9%的block沒(méi)有達(dá)到最小副本數(shù)(dfs.namenode.replication.min默認(rèn)值為1),集群處于安全模式,涉及BlockReport;
心跳相關(guān)配置
心跳間隔
屬性 | 值 | 解釋 |
---|---|---|
dfs.heartbeat.interval | 3 | Determines datanode heartbeat interval in seconds. |
- blockreport
屬性 | 值 | 解釋 |
---|---|---|
dfs.blockreport.intervalMsec | 21600000 (6小時(shí)) | Determines block reporting interval in milliseconds. |
-
查看hdfs-default.xml默認(rèn)配置文件
hdfs-default.xml默認(rèn)配置.png
負(fù)載均衡
- 什么原因會(huì)有可能造成不均衡?
- 機(jī)器與機(jī)器之間磁盤利用率不平衡是HDFS集群非常容易出現(xiàn)的情況。
- 尤其是在DataNode節(jié)點(diǎn)出現(xiàn)故障或在現(xiàn)有的集群上增添新的DataNode的時(shí)候。
- 為什么需要均衡?
- 提升集群存儲(chǔ)資源利用率。
- 從存儲(chǔ)與計(jì)算兩方面提高集群性能。
- 如何手動(dòng)負(fù)載均衡?
$HADOOP_HOME/sbin/start-balancer.sh -t 5% # 磁盤利用率最高的節(jié)點(diǎn)若比最少的節(jié)點(diǎn),大于5%,觸發(fā)均衡。
小結(jié):
- NameNode負(fù)責(zé)存儲(chǔ)元數(shù)據(jù),存在內(nèi)存中。
- DataNode負(fù)責(zé)存儲(chǔ)block塊及塊的元數(shù)據(jù)。
- SecondaryNameNode主要負(fù)責(zé)對(duì)HDFS元數(shù)據(jù)做checkpoint操作。
- 集群的心跳機(jī)制,讓集群中各節(jié)點(diǎn)形成一個(gè)整體;主節(jié)點(diǎn)知道從節(jié)點(diǎn)的死活。
- 節(jié)點(diǎn)的上下線,導(dǎo)致存儲(chǔ)的不均衡,可以手動(dòng)觸發(fā)負(fù)載均衡。