NameNode 和 SecondaryNameNode

目錄

一、NN和2NN工作機制

二、NN和2NN工作機制詳解

三、Fsimage 和 Edits解析

四、oev查看Edits文件

五、CheckPoint 時間設置

六、 NameNode故障處理

七、集羣安全模式

八、NameNode多目錄配置


一、NN和2NN工作機制


思考:NameNode中的元數據是存儲在哪裏的?
首先,我們做個假設,如果存儲在 NameNode節點的磁盤中,因爲經常需要進行隨機訪問,還有響應客戶請求,必然是效率過低。因此,元數據需要存放在內存中。但如果只存在內存中,一旦斷電,元數據丟失,整個集羣就無法工作了。因此需要對內存中的數據在磁盤中進行備份,備份元數據的 FsImage

這樣又會帶來新的問題,當在內存中的元數據更新時,如果同時更新FsImage,就會導致效率過低,但如果不更新,就會發生一致性問題,一旦 NameNode節點斷電,就會產生數據丟失。因此,引入Edits文件(只進行追加操作,效率很高)。每當元數據有更新或者添加元數據時,修改內存中的元數據並追加到 Edits中。這樣,一旦 NameNode節點斷電,可以通過 FsImage和 Edits的合併,合成元數據。

但是,如果長時間添加數據到Edits中,會導致該文件數據過大,效率降低,而且一旦斷電,恢復元數據需要的時間過長。因此,需要定期進行 FsImage和 Edits的合併,如果這個操作由 NameNode節點完成,又會效率過低。因此,引入一個新的節點SecondaryNamenode,專門用於 FsImage和 Edits的合併。NN 和 2NN工作機制,如下圖所示。

第一階段:NameNode啓動
(1)第一次啓動NameNode格式化後,創建Fsimage和Edits文件。如果不是第一次啓動,直接加載編輯日誌和鏡像文件到內存。
(2)客戶端對元數據進行增刪改的請求。
(3)NameNode記錄操作日誌,更新滾動日誌。
(4)NameNode在內存中對數據進行增刪改。

第二階段:Secondary NameNode工作
(1)Secondary NameNode詢問 NameNode是否需要 CheckPoint。直接帶回 NameNode是否檢查結果。
(2)Secondary NameNode請求執行CheckPoint。
(3)NameNode滾動正在寫的Edits日誌。
(4)將滾動前的編輯日誌和鏡像文件拷貝到Secondary NameNode。
(5)Secondary NameNode加載編輯日誌和鏡像文件到內存,併合並。
(6)生成新的鏡像文件fsimage.chkpoint。
(7)拷貝fsimage.chkpoint到NameNode。
(8)NameNode將fsimage.chkpoint重新命名成fsimage。

二、NN和2NN工作機制詳解


Fsimage:NameNode內存中元數據序列化後形成的文件。
Edits:記錄客戶端更新元數據信息的每一步操作(可通過Edits運算出元數據)。
NameNode啓動時,先滾動 Edits並生成一個空的 edits.inprogress,然後加載 Edits和 Fsimage到內存中,此時 NameNode內存就持有最新的元數據信息。Client開始對NameNode發送元數據的增刪改的請求,這些請求的操作首先會被記錄到edits.inprogress中(查詢元數據的操作不會被記錄在 Edits中,因爲查詢操作不會更改元數據信息),如果此時 NameNode掛掉,重啓後會從Edits中讀取元數據的信息。然後,NameNode會在內存中執行元數據的增刪改的操作。

由於 Edits中記錄的操作會越來越多,Edits文件會越來越大,導致 NameNode在啓動加載 Edits時會很慢,所以需要對 Edits和Fsimage進行合併(所謂合併,就是將 Edits和 Fsimage加載到內存中,照着 Edits中的操作一步步執行,最終形成新的Fsimage)。SecondaryNameNode的作用就是幫助 NameNode進行 Edits和 Fsimage的合併工作。

SecondaryNameNode首先會詢問 NameNode是否需要 CheckPoint(觸發 CheckPoint需要滿足兩個條件中的任意一個,定時時間到和Edits中數據寫滿了)。直接帶回 NameNode是否檢查結果。SecondaryNameNode執行 CheckPoint操作,首先會讓NameNode滾動 Edits並生成一個空的 edits.inprogress,滾動 Edits的目的是給 Edits打個標記,以後所有新的操作都寫入edits.inprogress,其他未合併的 Edits和 Fsimage會拷貝到 SecondaryNameNode的本地,然後將拷貝的 Edits和 Fsimage加載到內存中進行合併,生成 fsimage.chkpoint,然後將 fsimage.chkpoint拷貝給 NameNode,重命名爲 Fsimage後替換掉原來的Fsimage。NameNode在啓動時就只需要加載之前未合併的 Edits和 Fsimage即可,因爲合併過的 Edits中的元數據信息已經被記錄在 Fsimage中。

三、Fsimage 和 Edits解析


NameNode被格式化之後,將在 /opt/module/hadoop-2.7.2/data/tmp/dfs/name/current 目錄中產生如下文件:

(1)Fsimage文件:HDFS文件系統元數據的一個永久性的檢查點,其中包含 HDFS文件系統的所有目錄和文件idnode的序列化信息。
(2)Edits文件:存放 HDFS文件系統的所有更新操作的路徑,文件系統客戶端執行的所有寫操作首先會被記錄到 edits文件中。
(3)seen_txid文件保存的是一個數字,就是最後一個edits_的數字,表示未更新到 Fsimage 中的 Edits 日誌。
(4)每次 Namenode啓動的時候都會將 fsimage文件讀入內存,並從00001開始到 seen_txid中記錄的數字依次執行每個 edits裏面的更新操作,保證內存中的元數據信息是最新的、同步的,可以看成 Namenode啓動的時候就將 fsimage和 edits文件進行了合併。

oiv 查看 Fsimage文件:(1)查看 oiv和 oev命令

[root@hadoop1 current]$ hdfs
oiv      apply the offline fsimage viewer to an fsimage
oev      apply the offline edits viewer to an edits file

(2)基本語法:

hdfs oiv -p 文件類型 -i鏡像文件 -o 轉換後文件輸出路徑

(3)案例實操:

[root@hadoop1 current]$ pwd
/opt/module/hadoop-2.7.2/data/tmp/dfs/name/current

[root@hadoop1 current]$ hdfs oiv -p XML -i fsimage_0000000000000000025 -o /opt/module/hadoop-2.7.2/fsimage.xml

[root@hadoop1 current]$ cat /opt/module/hadoop-2.7.2/fsimage.xml

查看 fsimage.xml 中的內容顯示結果如下。

<inode>
	<id>16386</id>
	<type>DIRECTORY</type>
	<name>user</name>
	<mtime>1512722284477</mtime>
	<permission>atguigu:supergroup:rwxr-xr-x</permission>
	<nsquota>-1</nsquota>
	<dsquota>-1</dsquota>
</inode>

<inode>
	<id>16387</id>
	<type>DIRECTORY</type>
	<name>atguigu</name>
	<mtime>1512790549080</mtime>
	<permission>atguigu:supergroup:rwxr-xr-x</permission>
	<nsquota>-1</nsquota>
	<dsquota>-1</dsquota>
</inode>

<inode>
	<id>16389</id>
	<type>FILE</type>
	<name>wc.input</name>
	<replication>3</replication>
	<mtime>1512722322219</mtime>
	<atime>1512722321610</atime>
	<perferredBlockSize>134217728</perferredBlockSize>
	<permission>atguigu:supergroup:rw-r--r--</permission>
	<blocks>
		<block>
			<id>1073741825</id>
			<gnstamp>1001</genstamp>
			<numBytes>59</numBytes>
		</block>
	</blocks>
</inode >

思考:可以看出,Fsimage中沒有記錄塊所對應 DataNode,爲什麼?
在集羣啓動後,要求 DataNode上報數據塊信息,並間隔一段時間後再次上報。

四、oev查看Edits文件


【1】基本語法

hdfs oev -p 文件類型 -i編輯日誌 -o 轉換後文件輸出路徑

【2】案例實操

[root@hadoop1 current]$ hdfs oev -p XML -i edits_0000000000000000012-0000000000000000013 -o /opt/module/hadoop-2.7.2/edits.xml

[root@hadoop1 current]$ cat /opt/module/hadoop-2.7.2/edits.xml

查看 edits.xml 中的內容顯示結果如下。

<?xml version="1.0" encoding="UTF-8"?>
<EDITS>
	<EDITS_VERSION>-63</EDITS_VERSION>
	<RECORD>
		<OPCODE>OP_START_LOG_SEGMENT</OPCODE>
		<DATA>
			<TXID>129</TXID>
		</DATA>
	</RECORD>
	<RECORD>
		<OPCODE>OP_ADD</OPCODE>
		<DATA>
			<TXID>130</TXID>
			<LENGTH>0</LENGTH>
			<INODEID>16407</INODEID>
			<PATH>/hello7.txt</PATH>
			<REPLICATION>2</REPLICATION>
			<MTIME>1512943607866</MTIME>
			<ATIME>1512943607866</ATIME>
			<BLOCKSIZE>134217728</BLOCKSIZE>
			<CLIENT_NAME>DFSClient_NONMAPREDUCE_-1544295051_1</CLIENT_NAME>
			<CLIENT_MACHINE>192.168.1.5</CLIENT_MACHINE>
			<OVERWRITE>true</OVERWRITE>
			<PERMISSION_STATUS>
				<USERNAME>atguigu</USERNAME>
				<GROUPNAME>supergroup</GROUPNAME>
				<MODE>420</MODE>
			</PERMISSION_STATUS>
			<RPC_CLIENTID>908eafd4-9aec-4288-96f1-e8011d181561</RPC_CLIENTID>
			<RPC_CALLID>0</RPC_CALLID>
		</DATA>
	</RECORD>
	<RECORD>
		<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
		<DATA>
			<TXID>131</TXID>
			<BLOCK_ID>1073741839</BLOCK_ID>
		</DATA>
	</RECORD>
</EDITS >

思考:NameNode如何確定下次開機啓動的時候合併哪些Edits?
NameNode啓動的時候合併的是上次停機前正在寫入的Edits,即edits_inprogress_xxx

五、CheckPoint 時間設置


【1】通常情況下,SecondaryNameNode每隔一小時執行一次。[hdfs-default.xml]

<property>
    <name>dfs.namenode.checkpoint.period</name>
    <value>3600</value>
</property>

【2】一分鐘檢查一次操作次數,當操作次數達到1百萬時,SecondaryNameNode執行一次。

<property>
    <name>dfs.namenode.checkpoint.txns</name>
    <value>1000000</value>
    <description>操作動作次數</description>
</property>


<property>
    <name>dfs.namenode.checkpoint.check.period</name>
    <value>60</value>
    <description> 1分鐘檢查一次操作次數</description>
</property >

六、 NameNode故障處理


NameNode故障後,可以採用如下兩種方法恢復數據。

方法一:將 SecondaryNameNode數據拷貝到 NameNode存儲數據的目錄;
【1】kill -9 NameNode進程;
【2】刪除 NameNode存儲的數據(/opt/module/hadoop-2.7.2/data/tmp/dfs/name);

[root@hadoop1 hadoop-2.7.2]$ rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

【3】 拷貝 SecondaryNameNode中數據到原NameNode存儲數據目錄

[root@hadoop1 dfs]$ scp -r root@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/* ./name/

【4】重新啓動 NameNode

[root@hadoop1 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start namenode

方法二:使用  -importCheckpoint 選項啓動 NameNode守護進程,從而將 SecondaryNameNode中數據拷貝到 NameNode目錄
【1】修改 hdfs-site.xml中的;

<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>120</value>
</property>

<property>
  <name>dfs.namenode.name.dir</name>
  <value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value>
</property>

【2】kill -9 NameNode進程;
【3】刪除 NameNode存儲的數據(/opt/module/hadoop-2.7.2/data/tmp/dfs/name);

[root@hadoop102 hadoop-2.7.2]$ rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

【4】如果 SecondaryNameNode不和 NameNode在一個主機節點上,需要將 SecondaryNameNode存儲數據的目錄拷貝到NameNode存儲數據的平級目錄,並刪除 in_use.lock文件

[root@hadoop102 dfs]$ scp -r root@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary ./

[root@hadoop102 namesecondary]$ rm -rf in_use.lock

[root@hadoop102 dfs]$ pwd
/opt/module/hadoop-2.7.2/data/tmp/dfs

[root@hadoop102 dfs]$ ls
data  name  namesecondary

【5】導入檢查點數據(等待一會ctrl+c結束掉)

[root@hadoop1 hadoop-2.7.2]$ bin/hdfs namenode -importCheckpoint

【6】啓動NameNode

[root@hadoop1 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start namenode

七、集羣安全模式


Namenode啓動時,首先將映像文件(fsimage)載入內存,並執行編輯日誌(edits)中的各項操作。一旦在內存中成功建立文件系統元數據的映像,則創建一個新的fsimage文件和一個空的編輯日誌。此時,namenode開始監聽 datanode請求。但是此刻,namenode運行在安全模式,即 namenode的文件系統對於客戶端來說是隻讀的。

系統中的數據塊的位置並不是由namenode維護的,而是以塊列表的形式存儲在datanode中。在系統的正常操作期間,namenode會在內存中保留所有塊位置的映射信息。在安全模式下,各個datanode會向namenode發送最新的塊列表信息,namenode瞭解到足夠多的塊位置信息之後,即可高效運行文件系統。

如果滿足“最小複本條件”,namenode會在30秒鐘之後就退出安全模式。所謂的最小複本條件指的是在整個文件系統中99.9%的塊滿足最小複本級別(默認值:dfs.replication.min=1)。在啓動一個剛剛格式化的HDFS集羣時,因爲系統中還沒有任何塊,所以namenode不會進入安全模式。

【1】基本語法:集羣處於安全模式,不能執行重要操作(寫操作)。集羣啓動完成後,自動退出安全模式。
(1)bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式狀態)
(2)bin/hdfs dfsadmin -safemode enter   (功能描述:進入安全模式狀態)
(3)bin/hdfs dfsadmin -safemode leave (功能描述:離開安全模式狀態)
(4)bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式狀態)
【2】 案例:模擬等待安全模式
(1)查看當前模式

[root@hadoop1 hadoop-2.7.2]$ hdfs dfsadmin -safemode get
Safe mode is OFF

(2)先進入安全模式

[root@hadoop1 hadoop-2.7.2]$ bin/hdfs dfsadmin -safemode enter

(3)創建並執行下面的腳本:在/opt/module/hadoop-2.7.2路徑上,編輯一個腳本safemode.sh

[root@hadoop1 hadoop-2.7.2]$ touch safemode.sh
[root@hadoop1 hadoop-2.7.2]$ vim safemode.sh

#!/bin/bash
hdfs dfsadmin -safemode wait
hdfs dfs -put /opt/module/hadoop-2.7.2/README.txt /

[root@hadoop1 hadoop-2.7.2]$ chmod 777 safemode.sh
[root@hadoop1 hadoop-2.7.2]$ ./safemode.sh 

(4)再打開一個窗口,執行

[root@hadoop1 hadoop-2.7.2]$ bin/hdfs dfsadmin -safemode leave

(5)觀察上一個窗口,會發現執行了腳本中上傳數據的操作。並發現 HDFS集羣上已經有上傳的數據了。

Safe mode is OFF

八、NameNode多目錄配置


NameNode 的本地目錄可以配置成多個,且每個目錄存放內容相同,增加了可靠性。
具體配置如下
【1】在 hdfs-site.xml文件中增加如下內容

<property>
    <name>dfs.namenode.name.dir</name>
    <value>file:///${hadoop.tmp.dir}/dfs/name1,file:///${hadoop.tmp.dir}/dfs/name2</value>
</property>

【2】停止集羣,刪除 data和 logs中所有數據。

[root@hadoop1 hadoop-2.7.2]$ rm -rf data/ logs/
[root@hadoop2 hadoop-2.7.2]$ rm -rf data/ logs/
[root@hadoop3 hadoop-2.7.2]$ rm -rf data/ logs/

【3】格式化集羣並啓動。

[root@hadoop1 hadoop-2.7.2]$ bin/hdfs namenode –format
[root@hadoop1 hadoop-2.7.2]$ sbin/start-dfs.sh

【4】向NameNode中上傳數據,並查看結果,發現兩者的內容一模一樣。保證 NameNode的可靠性。

[root@hadoop1 dfs]$ ll
總用量 12
drwx------. 3 root root 4096 12月 11 08:03 data
drwxrwxr-x. 3 root root 4096 12月 11 08:03 name1
drwxrwxr-x. 3 root root 4096 12月 11 08:03 name2


  ----架構師資料,關注公衆號獲取----

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章