學習目标:了解namenode的工作機制尤其是中繼資料管理機制,以增強對hdfs工作原理的了解,及培養hadoop叢集營運中“性能調優”、“namenode”故障問題的分析解決能力
問題場景:
1、叢集啟動後,可以檢視目錄,但是上傳檔案時報錯,打開web頁面可看到namenode正處于safemode狀态,怎麼處理?
解釋:
safemode是namenode的一種狀态(active/standby/safemode安全模式)
namenode進入安全模式的原理:
a、namenode發現叢集中的block丢失率達到一定比例時(0.01%),namenode就會進入安全模式,在安全模式下,用戶端不能對任何資料進行操作,隻能檢視中繼資料資訊(比如ls/mkdir)
b、如何退出安全模式?
找到問題所在,進行修複(比如修複當機的datanode)
或者可以手動強行退出安全模式(沒有真正解決問題): hdfs namenode--safemode leave
c、在hdfs叢集正常冷啟動時,namenode也會在safemode狀态下維持相當長的一段時間,此時你不需要去理會,等待它自動退出安全模式即可
(原理:
namenode的記憶體中繼資料中,包含檔案路徑、副本數、blockid,及每一個block所在datanode的資訊,而fsimage中,不包含block所在的datanode資訊,那麼,當namenode冷啟動時,此時記憶體中的中繼資料隻能從fsimage中加載而來,進而就沒有block所在的datanode資訊——>就會導緻namenode認為所有的block都已經丢失——>進入安全模式——>datanode啟動後,會定期向namenode彙報自身所持有的blockid資訊,——>随着datanode陸續啟動,進而陸續彙報block資訊,namenode就會将記憶體中繼資料中的block所在datanode資訊補全更新——>找到了所有block的位置,進而自動退出安全模式)
2、namenode伺服器的磁盤故障導緻namenode當機,如何挽救叢集及資料?
3、namenode是否可以有多個?namenode記憶體要配置多大?namenode跟叢集資料存儲能力有關系嗎?
4、檔案的blocksize究竟調大好還是調小好?--結合mapreduce
……
諸如此類問題的回答,都需要基于對namenode自身的工作原理的深刻了解
namenode職責:
<a target="_blank">負責用戶端請求的響應</a>
<a target="_blank">中繼資料的管理(查詢,修改)</a>
namenode對資料的管理采用了三種存儲形式:
記憶體中繼資料(namesystem)
磁盤中繼資料鏡像檔案
資料記錄檔檔案(可通過日志運算出中繼資料)
<a target="_blank"> </a>
dfs.namenode.checkpoint.check.period=60 #檢查觸發條件是否滿足的頻率,60秒
dfs.namenode.checkpoint.dir=file://${hadoop.tmp.dir}/dfs/namesecondary
#以上兩個參數做checkpoint操作時,secondary namenode的本地工作目錄
dfs.namenode.checkpoint.edits.dir=${dfs.namenode.checkpoint.dir}
dfs.namenode.checkpoint.max-retries=3 #最大重試次數
dfs.namenode.checkpoint.period=3600 #兩次checkpoint之間的時間間隔3600秒
dfs.namenode.checkpoint.txns=1000000 #兩次checkpoint之間最大的操作記錄
namenode和secondary namenode的工作目錄存儲結構完全相同,是以,當namenode故障退出需要重新恢複時,可以從secondary namenode的工作目錄中将fsimage拷貝到namenode的工作目錄,以恢複namenode的中繼資料
在第一次部署好hadoop叢集的時候,我們需要在namenode(nn)節點上格式化磁盤:
$hadoop_home/bin/hdfs namenode -format
格式化完成之後,将會在$dfs.namenode.name.dir/current目錄下如下的檔案結構
其中的dfs.name.dir是在hdfs-site.xml檔案中配置的,預設值如下:
dfs.namenode.name.dir屬性可以配置多個目錄,
如/data1/dfs/name,/data2/dfs/name,/data3/dfs/name,....。各個目錄存儲的檔案結構和内容都完全一樣,相當于備份,這樣做的好處是當其中一個目錄損壞了,也不會影響到hadoop的中繼資料,特别是當其中一個目錄是nfs(網絡檔案系統network filesystem,nfs)之上,即使你這台機器損壞了,中繼資料也得到儲存。
下面對$dfs.namenode.name.dir/current/目錄下的檔案進行解釋。
1、version檔案是java屬性檔案,内容大緻如下:
其中
(1)、namespaceid是檔案系統的唯一辨別符,在檔案系統首次格式化之後生成的;
(2)、storagetype說明這個檔案存儲的是什麼程序的資料結構資訊(如果是datanode,storagetype=data_node);
(3)、ctime表示namenode存儲時間的建立時間,由于我的namenode沒有更新過,是以這裡的記錄值為0,以後對namenode更新之後,ctime将會記錄更新時間戳;
(4)、layoutversion表示hdfs永久性資料結構的版本資訊, 隻要資料結構變更,版本号也要遞減,此時的hdfs也需要更新,否則磁盤仍舊是使用舊版本的資料結構,這會導緻新版本的namenode無法使用;
(5)、clusterid是系統生成或手動指定的叢集id,在-clusterid選項中可以使用它;如下說明
a、使用如下指令格式化一個namenode:
$hadoop_home/bin/hdfs namenode -format [-clusterid<cluster_id>]
選擇一個唯一的cluster_id,并且這個cluster_id不能與環境中其他叢集有沖突。如果沒有提供cluster_id,則會自動生成一個唯一的clusterid。
b、使用如下指令格式化其他namenode:
$hadoop_home/bin/hdfs namenode -format-clusterid <cluster_id>
c、更新叢集至最新版本。在更新過程中需要提供一個clusterid,例如:
$hadoop_prefix_home/bin/hdfs start namenode --config$hadoop_conf_dir -upgrade -clusterid <cluster_id>
如果沒有提供clusterid,則會自動生成一個clusterid。
(6)、blockpoolid:是針對每一個namespace所對應的blockpool的id,上面的這個bp-893790215-192.168.24.72-1383809616115就是在我的ns1的namespace下的存儲塊池的id,這個id包括了其對應的namenode節點的ip位址。
2、$dfs.namenode.name.dir/current/seen_txid非常重要,是存放transactionid的檔案,format之後是0,它代表的是namenode裡面的edits_*檔案的尾數,namenode重新開機的時候,會按照seen_txid的數字,循序從頭跑edits_0000001~到seen_txid的數字。是以當你的hdfs發生異常重新開機的時候,一定要比對seen_txid内的數字是不是你edits最後的尾數,不然會發生建置namenode時metadata的資料有缺少,導緻誤删datanode上多餘block的資訊。
3、$dfs.namenode.name.dir/current目錄下在format的同時也會生成fsimage和edits檔案,及其對應的md5校驗檔案。
補充:seen_txid
檔案中記錄的是edits滾動的序号,每次重新開機namenode時,namenode就知道要将哪些edits進行加載edits