大資料(六):NameNode工作機制
一、NameNode和Secondary NameNode工作機制
左側為NameNode 右側為Secondary NameNode
1.第一階段:namenode啟動
-
第一次啟動namenode格式化後,建立fsimage和edits檔案,如果不是第一次啟動,直接載入編輯日誌和映象檔案到記憶體。
-
客戶端對元資料映象增刪改的請求
-
namenode記錄操作日誌,更新滾動日誌
-
namenode在記憶體中對資料映象增刪改查
2.第二階段:Secondary NameNode工作
-
Secondary NameNode詢問namenode是否需要checkpoint。直接帶回namenode是否檢查結果
-
Secondary NameNode請求執行checkpoint
-
namenode滾動正在寫的edits日誌
-
將滾動前的編輯日誌和映象檔案拷貝到Secondary NameNode
-
Secondary NameNode載入編輯日誌和映象檔案到記憶體,開始合併。
-
生成新的映象檔案fsimage.chkpoint
-
拷貝fsimage.chkpoint到namenode
-
nodenode將fsimage.chkpoint重新命名成fsimage
二、映象檔案和編輯日誌
namenode被格式化之後,將在日誌存放的地方生成四個檔案(預設在/tmp/hadopp-使用者名稱/dfs/home/current目錄中)
-
Fsimage檔案:HDFS檔案系統元資料的一個永久性檢查點,其中包含HDFS檔案系統的所有目錄和檔案idnode的序列化資訊
-
Edits檔案:存放HDFS檔案系統的所有更新操作的路徑,檔案系統客戶端執行的所有寫操作首先會被記錄到edits檔案中。
-
seen_txid檔案儲存的是一個數字,就是最後一個edits_的數字
-
VERSION檔案:namenode版本號
-
每次Namenode啟動的時候都會將fsimage檔案讀入記憶體,並從00001開始到seen_txid中記錄的數字依次執行每個edits裡面的更新操作,保證記憶體的元資料資訊是最新的、同步的,可以看成Namenode啟動的時候就將fsimage和edits檔案進行了合併。
三、檢視fsimage檔案和edits檔案
1.使用oiv命令檢視fsimage檔案
hdfs oiv -p 轉換成的檔案型別 -i fsimage檔案路徑 -o 轉換後文件輸出的路徑
-
一般轉換為xml型別
2.使用oev命令檢視edits檔案
hdfs oev -p 轉換成的檔案型別 -i fsimage檔案路徑 -o 轉換後文件輸出的路徑
3.使用dfsadmin命令滾動編輯日誌
hdfs dfsadmin -rolledits
-
一般在測試的時候使用
-
會將之前的日誌檔案打包成舊版本,生成新的增量日誌
四、檢視VERSION檔案
-
namespaceID在HDFS上,會有多個namenode,所以不同namenode的namespaceID是不同的,分別管理一組blockpoolID
-
clusterID叢集id,全域性唯一
-
cTime屬性標記了namenode儲存系統的建立時間,對於剛剛格式化的檔案系統,這個屬性為0;但是在檔案系統升級之後,該值會更新到新的時間戳
-
storageType屬性說明該儲存目錄包含的是namenode的資料結構
-
blockpoolID:一個block pool id標識一個block pool,並且是跨叢集的全域性唯一,當一個新的Namespace被建立的時候(format過程的一部分)會建立並持久化一個唯一ID。在建立工程構建全域性唯一的BlockPoolID比人為的配置更可靠一些。NN將BlockPoolID持久化到磁碟中,在後續的啟動過程中,會再次load並使用。
-
layoutVersion是一個負整數,通常只有HDFS增加新特性時才會更新這個版本號。
五、修改SecondaryNameNode檢查點時間
hdfs-default.xml
1.通常情況下,SecondaryNameNode每個一小時執行一次
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
</property>
2.一分鐘檢查一次操作次數,當操作次數達到1百萬次,SecondaryNameNode也將執行一次
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
</property>
#六十秒檢測一次操作次數
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60</value>
</property>
六、NameNode故障處理
NameNode故障後,可以採用以下兩種方法恢復資料。
-
將SecondaryNameNode中資料拷貝到namenode儲存資料的目錄中
-
使用-importCheckpoint選項啟動namenode守護程序,從而將SecondaryNameNode中資料拷貝到namenode目錄中
1.手動拷貝SecondaryNameNode資料
-
模擬NameNode故障,手動殺死namenode程序kill -9 namenode程序
-
刪除namenode儲存的資料(預設在/tmp/hadoop-使用者名稱/dfs/name)rm -rf /tmp/hadoop-使用者名稱/dfs/name/*
-
拷貝SecondaryNameNode中資料拷貝到原namenode儲存資料目錄中(SecondaryNameNode資料預設在/tmp/hadoop-使用者名稱/dfs/namesecondary)
-
重啟namenode hadoop-daemon.sh start namenode
2.通過-importCheckpoint修復資料
修改hdfs-site.xml
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>120</value>
</property>
<property
<name>dfs.namenode.name.dir</name>
<value>{namenode資料檔案所在的路徑}</value>
</property>
-
模擬NameNode故障,手動殺死namenode程序kill -9 namenode程序
-
刪除namenode儲存的資料(預設在/tmp/hadoop-使用者名稱/dfs/name)rm -rf /tmp/hadoop-使用者名稱/dfs/name/*
-
如果SecondaryNameNode不和Namenode在一個主機節點上,需要將SecondaryNameNode儲存資料的目錄拷貝到Namenode儲存資料的平級目錄,並刪除掉in_use.lock檔案
-
執行hdfs namenode -importCheckpoint
-
重啟namenode hadoop-daemon.sh start namenode
七、叢集安全模式操作
NameNode啟動時,首先將映像檔案(fsimage)載入記憶體,並執行編輯日誌(edits)中的各項操作,一旦在記憶體中成功建立檔案系統元資料的映像,則建立一個新的fsimage檔案和一個空的編輯日誌。此時namenode開始監聽datanode請求。但是此刻,namenode執行在安全模式,即namenode的檔案系統對於客戶端來說是隻讀的
系統中的資料塊的位置並不是由namenode維護的,而是以塊列表的形式儲存在datanode中。在系統的正常操作期間,namenode會在記憶體中保留所有塊位置的對映資訊。在安全模式下,各個datanode會向namenode傳送最新的快列表資訊,namenode瞭解到最夠多的塊位置資訊之後,即可高效執行檔案系統。
如果滿足“最小副本條件”,namenode會在30秒鐘之後就退出安全模式。所謂的最小副本條件指的是在整個檔案系統中99%的塊滿足最小副本級別(預設值:dfs.replication.min=1)。在啟動一個剛剛格式化的HDFS叢集時,應為系統中還沒有任何塊,所以namenode不會進入安全模式
1.基本語法
叢集處於安全模式,不能執行重要操作(寫操作)。叢集啟動完成後,自動退出安全模式。
-
檢視安全模式狀態:hdfs dfsadmin -safenode get
-
進入安全模式狀態:hdfs dfsadmin -safenode enter
-
退出安全模式狀態:hdfs dfsadmin -safenode leave
-
等待安全模式狀態:hdfs dfsadmin -safenode wait
2.使用等待安全模式
-
先進入安全模式
-
編寫一個指令碼,執行指令碼
#!/bin/bash
hdfs dfsadmin -safenode wait
#當退出安全模式之後指令碼將繼續向下執行
hdfs dfs -put ~/hello.txt /root/hello.txt
八、namenode多目錄配置
namenode的本地目錄可以配置成多個,且每個目錄存放內容相同,增加了可靠性。
-
停止叢集,並刪除data和logs中所有資料
-
配置hdfs-site.xml檔案,重新格式化hdfs並啟動
<property>
<name>dfs.namenode.name.dir</name>
<value>file://{檔案放的路徑}/dfs/name1,file://{檔案放的路徑}/dfs/name2</value>
</property>