前段時間公司hadoop叢集當機,發現是namenode磁盤滿了, 清理出部分空間後,重新開機叢集時,重新開機失敗。
又發現叢集Secondary namenode 服務也恰恰壞掉,導緻所有的操作log持續寫入edits.new 檔案,等叢集當機的時候檔案大小已經達到了喪心病狂的70G+..重新開機叢集報錯 加載edits檔案失敗。分析加載檔案報錯原因是磁盤不足導緻最後寫入的log隻寫入一半就當機了。由于log不完整,hadoop再次啟動加載edits檔案時讀取檔案報錯。由于edits.new 檔案過大,存儲了好多操作log,是以必須要對其進行修複。
嘗試删除檔案的最後幾行,結果還是報錯。于是檢視源碼對edits 檔案結構進行分析發現是二進制格式,首行為版本号,然後是hadoop運作過程中的log記錄内容,由操作碼 +長度(非必須)+其他項組成。

NameNode函數裡調用FSNamesystemm讀取dfs.namenode.name.dir和dfs.namenode.edits.dir建構FSDirectory。
FSImage類recoverTransitionRead和saveNameSpace分别實作了中繼資料的檢查、加載、記憶體合并和中繼資料的持久化存儲。
saveNameSpace将中繼資料寫入到磁盤,具體操作步驟:首先将current目錄重命名為lastcheckpoint.tmp;然後在建立新的current目錄,并儲存檔案;最後将lastcheckpoint.tmp重命名為privios.checkpoint.
checkPoint的過程:Secondary NameNode會通知nameNode産生一個edit log檔案edits.new,之後所有的日志操作寫入到edits.new檔案中。接下來Secondary NameNode會從namenode下載下傳fsimage和edits檔案,進行合并産生新的fsimage.ckpt;然後Secondary會将fsimage.ckpt檔案上傳到namenode。最後namenode會重命名fsimage.ckpt為fsimage,edtis.new為edits;