思考:NameNode中的元數(shù)據(jù)是存儲(chǔ)在哪里的?
??首先,我們做個(gè)假設(shè)圈驼,如果存儲(chǔ)在NameNode節(jié)點(diǎn)的磁盤(pán)中,因?yàn)榻?jīng)常需要進(jìn)行隨機(jī)訪 問(wèn)枚荣,還有響應(yīng)客戶請(qǐng)求碗脊,必然是效率過(guò)低。因此橄妆,元數(shù)據(jù)需要存放在內(nèi)存中衙伶。但如果只存在內(nèi)存中,一旦斷電害碾,元數(shù)據(jù)丟失矢劲,整個(gè)集群就無(wú)法工作了。因此產(chǎn)生在磁盤(pán)中備份元數(shù)據(jù)的FsImage慌随。
??這樣又會(huì)帶來(lái)新的問(wèn)題芬沉,當(dāng)在內(nèi)存中的元數(shù)據(jù)更新時(shí),如果同時(shí)更新FsImage阁猜,就會(huì)導(dǎo)致效率過(guò)低丸逸,但如果不更新,就會(huì)發(fā)生一致性問(wèn)題剃袍,一旦NameNode節(jié)點(diǎn)斷電黄刚,就會(huì)產(chǎn)生數(shù)據(jù)丟失。因此民效,引入Edits文件(只進(jìn)行追加操作憔维,效率很高)。每當(dāng)元數(shù)據(jù)有更新或者添加元數(shù)據(jù)時(shí)畏邢,修改內(nèi)存中的元數(shù)據(jù)并追加到Edits中业扒。這樣,一旦NameNode節(jié)點(diǎn)斷電舒萎,可以通過(guò)FsImage和Edits的合并程储,合成元數(shù)據(jù)。
??但是逆甜,如果長(zhǎng)時(shí)間添加數(shù)據(jù)到Edits中虱肄,會(huì)導(dǎo)致該文件數(shù)據(jù)過(guò)大,效率降低交煞,而且一旦斷電,恢復(fù)元數(shù)據(jù)需要的時(shí)間過(guò)長(zhǎng)斟或。因此素征,需要定期進(jìn)行FsImage和Edits的合并,如果這個(gè)操作由NameNode節(jié)點(diǎn)完成,又會(huì)效率過(guò)低御毅。因此根欧,引入一個(gè)新的節(jié)點(diǎn)SecondaryNamenode,專門(mén)用于FsImage和Edits的合并端蛆。
- 第一階段:NameNode啟動(dòng)
(1)第一次啟動(dòng)NameNode格式化后凤粗,創(chuàng)建Fsimage和Edits文件。如果不是第一次啟動(dòng)今豆,直接加載編輯日志和鏡像文件到內(nèi)存嫌拣。
(2)客戶端對(duì)元數(shù)據(jù)進(jìn)行增刪改的請(qǐng)求。
(3)NameNode記錄操作日志呆躲,更新滾動(dòng)日志异逐。
(4)NameNode在內(nèi)存中對(duì)元數(shù)據(jù)進(jìn)行增刪改。 - 第二階段:Secondary NameNode工作
(1)Secondary NameNode詢問(wèn)NameNode是否需要CheckPoint插掂。直接帶回NameNode是否檢查結(jié)果灰瞻。
(2)Secondary NameNode請(qǐng)求執(zhí)行CheckPoint。
(3)NameNode滾動(dòng)正在寫(xiě)的Edits日志辅甥。
(4)將滾動(dòng)前的編輯日志和鏡像文件拷貝到Secondary NameNode酝润。
(5)Secondary NameNode加載編輯日志和鏡像文件到內(nèi)存,并合并璃弄。
(6)生成新的鏡像文件fsimage.chkpoint要销。
(7)拷貝fsimage.chkpoint到NameNode。
(8)NameNode將fsimage.chkpoint重新命名成fsimage谢揪。
NN和2NN工作機(jī)制詳解:
- Fsimage:NameNode內(nèi)存中元數(shù)據(jù)序列化后形成的文件蕉陋。
- Edits:記錄客戶端更新元數(shù)據(jù)信息的每一步操作(可通過(guò)Edits運(yùn)算出元數(shù)據(jù))。
??NameNode啟動(dòng)時(shí)拨扶,先滾動(dòng)Edits并生成一個(gè)空的edits.inprogress凳鬓,然后加載Edits和Fsimage到內(nèi)存中,此時(shí)NameNode內(nèi)存就持有最新的元數(shù)據(jù)信息患民。Client開(kāi)始對(duì)NameNode發(fā)送元數(shù)據(jù)的增刪改的請(qǐng)求缩举,這些請(qǐng)求的操作首先會(huì)被記錄到edits.inprogress中(查詢?cè)獢?shù)據(jù)的操作不會(huì)被記錄在Edits中,因?yàn)椴樵儾僮鞑粫?huì)更改元數(shù)據(jù)信息)匹颤,如果此時(shí)NameNode掛掉仅孩,重啟后會(huì)從Edits中讀取元數(shù)據(jù)的信息。然后印蓖,NameNode會(huì)在內(nèi)存中執(zhí)行元數(shù)據(jù)的增刪改的操作辽慕。
??由于Edits中記錄的操作會(huì)越來(lái)越多,Edits文件會(huì)越來(lái)越大赦肃,導(dǎo)致NameNode在啟動(dòng)加載Edits時(shí)會(huì)很慢溅蛉,所以需要對(duì)Edits和Fsimage進(jìn)行合并(所謂合并公浪,就是將Edits和Fsimage加載到內(nèi)存中,照著Edits中的操作一步步執(zhí)行船侧,最終形成新的Fsimage)欠气。SecondaryNameNode的作用就是幫助NameNode進(jìn)行Edits和Fsimage的合并工作。
??2NN首先會(huì)詢問(wèn)NN是否需要CheckPoint(觸發(fā)CheckPoint需要滿足兩個(gè)條件中的任意一個(gè)镜撩,定時(shí)時(shí)間到和Edits中數(shù)據(jù)寫(xiě)滿了)预柒。直接帶回NN是否檢查結(jié)果。2NN執(zhí)行CheckPoint操作袁梗,首先會(huì)讓NameNode滾動(dòng)Edits并生成一個(gè)空的edits.inprogress宜鸯,滾動(dòng)Edits的目的是給Edits打個(gè)標(biāo)記围段,以后所有新的操作都寫(xiě)入edits.inprogress顾翼,其他未合并的Edits和Fsimage會(huì)拷貝到2NN的本地,然后將拷貝的Edits和Fsimage加載到內(nèi)存中進(jìn)行合并奈泪,生成fsimage.chkpoint适贸,然后將fsimage.chkpoint拷貝給NameNode,重命名為Fsimage后替換掉原來(lái)的Fsimage涝桅。NameNode在啟動(dòng)時(shí)就只需要加載之前未合并的Edits和Fsimage即可拜姿,因?yàn)楹喜⑦^(guò)的Edits中的元數(shù)據(jù)信息已經(jīng)被記錄在Fsimage中。
CheckPoint時(shí)間設(shè)置
(1)通常情況下冯遂,SecondaryNameNode每隔一小時(shí)執(zhí)行一次蕊肥。
[hdfs-default.xml]
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
</property>
(2)一分鐘檢查一次操作次數(shù),當(dāng)操作次數(shù)達(dá)到1百萬(wàn)時(shí)蛤肌,SecondaryNameNode執(zhí)行一次壁却。
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>操作動(dòng)作次數(shù)</description>
</property>
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60</value>
<description> 1分鐘檢查一次操作次數(shù)</description>
</property >