背景
說點沒用的,我司進(jìn)行集群遷移闷旧,沒有用的測試機(jī)器要進(jìn)行格式化賣掉了长豁,然后突然一條偉大的命令,誤刪除了正在使用的hadoop集群所有節(jié)點的操作系統(tǒng)盤鸠匀,數(shù)據(jù)盤保留蕉斜,災(zāi)難就此來了逾柿。
hdfs 集群重建和數(shù)據(jù)恢復(fù)
HDFS metadata以樹狀結(jié)構(gòu)存儲整個HDFS上的文件和目錄缀棍,以及相應(yīng)的權(quán)限、配額和副本因子(replication factor)等机错。
nn啟動的時候:會將磁盤上的元數(shù)據(jù)加載到內(nèi)存中爬范,
磁盤中的元數(shù)據(jù)只有:
1)抽象目錄樹
2)數(shù)據(jù)和塊的對應(yīng)關(guān)系,
3)沒有 塊的存儲位置
磁盤上僅僅會存儲一個空的節(jié)點列表弱匪,這個節(jié)點列表是在datanode發(fā)送心跳報告之后填上的青瀑。
例如:/aa/hadoop2.7.6.tar.gz [blk_237838365:[],blk_237838366:[]]
而塊的存儲位置是在datanode向namenode發(fā)送心跳報告的時候匯報的,datanode向namenode匯報自己身上的塊的存儲信息萧诫。
例如:hadoop01:blk_237838365斥难,blk_237838366,blk_237838367
然后內(nèi)存接收datanode的心跳包 帘饶,補(bǔ)全塊的存儲位置列表整哑诊。
例如:/aa/hadoop2.7.6.tar.gz [blk_237838365:[hadoop01,hadoop02],blk_237838366:[hadoop01]]
NameNode
HDFS metadata主要存儲兩種類型的文件
1、fsimage
記錄某一永久性檢查點(Checkpoint)時整個HDFS的元信息
2及刻、edits
所有對HDFS的寫操作都會記錄在此文件中
3镀裤、Checkpoint介紹
standbynamenode HDFS會定期(dfs.namenode.checkpoint.period,默認(rèn)3600秒)的對最近的fsimage和一批新edits文件進(jìn)行Checkpoint(也可以手工命令方式)缴饭,Checkpoint發(fā)生后會將前一次Checkpoint后的所有edits文件合并到新的fsimage中暑劝,HDFS會保存最近兩次checkpoint的fsimage。Namenode啟動時會把最新的fsimage加載到內(nèi)存中颗搂。
基礎(chǔ)知識担猛。
1、namenode cat /export/hadoop/hdfs/namenode/current/VERSION
namespaceID=1242163293
clusterID=CID-124668a8-9b25-4ca7-97bf-5dd5c25041a9
cTime=1455091012961
storageType=NAME_NODE
blockpoolID=BP-180412957-40.32.10.18-1419305031110
layoutVersion=-60
layoutVersion
- HDFS metadata版本號,通常只有HDFS增加新特性時才會更新這個版本號
namespaceID/clusterID/blockpoolID
- 這三個ID在整個HDFS集群全局唯一傅联,作用是引導(dǎo)Datanode加入同一個集群智嚷。在HDFS Federation機(jī)制下,會有多個Namenode纺且,所以不同Namenode直接namespaceID是不同的盏道,分別管理一組blockpoolID,但是整個集群中载碌,clusterID是唯一的猜嘱,每次format namenode會生成一個新的,也可以使用-clusterid手工指定ID
namespaceID
是文件系統(tǒng)的唯一標(biāo)識嫁艇,是在文件系統(tǒng)首次格式化時設(shè)置的朗伶。
clusterID
是HDFS集群作為一個整體的唯一標(biāo)識。這兩個屬性對HDFS聯(lián)邦很重要步咪,因為一個集群可能由多個namespace組成论皆,每個namespace由一個NameNode管理。
blockpool
塊池的唯一標(biāo)識猾漫,塊池表示一個namespace下的所有文件点晴,由NameNode管理。
storageType
- 有兩種取值NAME_NODE /JOURNAL_NODE悯周,對于JournalNode的參數(shù)dfs.journalnode.edits.dir
粒督,其下的VERSION文件顯示的是JOURNAL_NODE
cTime
- HDFS創(chuàng)建時間,在升級后會更新該值
2禽翼、edits_start transaction ID-end transaction ID
finalized edit log segments屠橄,在HA環(huán)境中,Standby Namenode只能讀取finalized log segments闰挡,
3锐墙、edits_inprogress__start transaction ID
當(dāng)前正在被追加的edit log,HDFS默認(rèn)會為該文件提前申請1MB
doublebuffer空間以提升性能
4长酗、fsimage_end transaction ID
每次checkpoing(合并所有edits到一個fsimage的過程)產(chǎn)生的最終的fsimage溪北,同時會生成一個.md5的文件用來對文件做完整性校驗
5、seen_txid
保存最近一次fsimage或者edits_inprogress的transaction ID花枫。需要注意的是刻盐,這并不是Namenode當(dāng)前最新的transaction ID
,該文件只有在checkpoing(merge of edits into a fsimage)或者edit log roll(finalization of current edits_inprogress and creation of a new one)
時才會被更新劳翰。
這個文件的目的在于判斷在Namenode啟動過程中是否有丟失的edits敦锌,由于edits和fsimage可以配置在不同目錄,如果edits目錄被意外刪除了佳簸,最近一次checkpoint后的所有edits也就丟失了乙墙,導(dǎo)致Namenode狀態(tài)并不是最新的颖变,為了防止這種情況發(fā)生,Namenode啟動時會檢查seen_txid听想,如果無法加載到最新的transactions腥刹,Namenode進(jìn)程將不會完成啟動以保護(hù)數(shù)據(jù)一致性。
6汉买、in_use.lock
防止一臺機(jī)器同時啟動多個Namenode進(jìn)程導(dǎo)致目錄數(shù)據(jù)不一致
hdfs集群重建步驟衔峰,前提是從last+found找回了元數(shù)據(jù)
lost+found目錄的文件通常是未鏈接的文件(名字以及被刪除),這些文件還被一些進(jìn)程使用(數(shù)據(jù)沒有刪除)蛙粘,在系統(tǒng)突然關(guān)機(jī)時(內(nèi)核panic或突然斷電)出現(xiàn)垫卤。這些文件系統(tǒng)會刪除的,你不需要擔(dān)心出牧。當(dāng)因為軟件或硬件出現(xiàn)錯誤穴肘,導(dǎo)致文件系統(tǒng)不一致,也有可能把有問題的文件放入到lost+found目錄舔痕。它提供了恢復(fù)丟失文件的一種方法评抚。
1、看運維大佬能不能恢復(fù)磁盤伯复。
2慨代、查看NN和JN下面是不是還有沒有刪干凈的,注意lost+found下面也是可以用的边翼。
3鱼响、重建集群指定dfs.namenode.name.dir
,dfs.journalnode.edits.dir
组底,dfs.namenode.data.dir
配置要和故障集群一致,啟動新建集群筐骇,只啟動NN和JN债鸡,DN不啟動,觀察是否可以正常啟動铛纬。
4厌均、同步故障集群Blockpool ID,Namespace ID告唆,Cluster ID 到新建集群兩個namenode節(jié)點棺弊,同步點
NAME_NODE /export/hadoop/hdfs/namenode/current/VERSION
JOURNAL_NODE /export/hadoop/hdfs/journal/xcardata/current/VERSION
fsimage,edits擒悬,seen_txid 同步兩個nn一致
因為是拷貝數(shù)據(jù)節(jié)點的VERSION模她,所以datanode不需要修改。
如果集群沒有啟用Federation機(jī)制懂牧,那么Blockpool ID侈净,Namespace ID,Cluster ID全部一致,如果啟用Federation機(jī)制Blockpool ID畜侦,Namespace ID會有2套元扔,當(dāng)前集群是沒有啟用。
Federation是指HDFS集群可使用多個獨立的NameSpace(NameNode節(jié)點管理)來滿足HDFS命名空間的水平擴(kuò)展,【單機(jī)namenode的瓶頸大約是在4000臺集群旋膳,而后則需要使用聯(lián)邦機(jī)制】
這時候在DataNode上就不僅僅存儲一個Block Pool下的數(shù)據(jù)了,而是多個(大家可以在DataNode的datadir所在目錄里面查看BP-xx.xx.xx.xx打頭的目錄).
6澎语、重啟新集群,等待nn啟動加載fsimage和edit_image元數(shù)據(jù)和dn的block位置上報验懊。
7咏连、觀察監(jiān)控發(fā)現(xiàn)。
under replicated blocks 100w 副本數(shù)小于指定副本數(shù)的block數(shù)量
block with corrupted replication 108w 損壞塊個數(shù)
- 解決步驟
1鲁森、退出安全模式
hadoop dfsadmin -safemode leave
2祟滴、列出損壞文件,損壞的文件無法恢復(fù)歌溉,只能刪除
hdfs fsck /
3垄懂、只刪除有問題的塊文件,delete corrupted files
hdfs fsck -delete
補(bǔ)充
定位under replicated blocks痛垛,并解決
hdfs fsck / | grep 'Under replicated' | awk -F':' '{print $1}'
hadoop fs -setrep 3 /file_name
定位有問題塊
hdfs fsck / | egrep -v '^\.+$' | grep -v replica | grep -v Replica
打印出來塊位置信息
hdfs fsck /path/to/corrupt/file -locations -blocks -files
刪除問題塊
hdfs fs -rm /path/to/file/with/permanently/missing/blocks
獲取有關(guān)正在復(fù)制(或等待復(fù)制)的塊的信息
hadoop dfsadmin -metasave metasave-report.txt
文件metasave-report.txt 生成在/var/log/hadoop/hdfs/下
手動修復(fù)損壞的塊數(shù)據(jù) 草慧,釋放指定路徑上的租約,路徑必須位于HDFS文件系統(tǒng)上匙头。默認(rèn)重試次數(shù)為1漫谷。
lease recovery 的目的是當(dāng) Client 在寫入過程中掛了后,經(jīng)過一定的超時時間后蹂析,收回租約并關(guān)閉文件
hdfs debug recoverLease -path/path/to/corrupt/file -retries 10
自動修復(fù)損壞的塊數(shù)據(jù)
當(dāng)數(shù)據(jù)塊損壞后舔示,DN節(jié)點執(zhí)行directoryscan操作之前,都不會發(fā)現(xiàn)損壞电抚;
也就是directoryscan操作是間隔6h
dfs.datanode.directoryscan.interval : 21600
在DN向NN進(jìn)行blockreport前惕稻,都不會恢復(fù)數(shù)據(jù)塊;
也就是blockreport操作是間隔6h
dfs.blockreport.intervalMsec : 21600000
當(dāng)NN收到blockreport才會進(jìn)行恢復(fù)操作。
metasave-report.txt 測試環(huán)境
1 51298 files and directories, 29092 blocks = 80390 total
2 Live Datanodes: 3
3 Dead Datanodes: 0
4 Metasave: Blocks waiting for replication: 27359
5 /apps/hbase/data/WALs/yhg-hadoop-54188.xxx.com.cn,16020,1645421741628/yhg-hadoop-54188.xxx.com.cn%2C16020%2C1645421741628..meta.1645421772554.meta: blk_1074217482_487322 (replicas: l: 2 d: 0 c: 0 e: 0) 10.20.54.188:50010 : 10.20.54.186:50010 :
6 /apps/hbase/data/data/dalishen/test-media_user/63f4084799ca7ba20683b4215774531e/f/02b6bed1897946ef9cbdbf29ef46a4f6: blk_1074217498_487338 (replicas: l: 2 d: 0 c: 0 e: 0) 10.20.54.188:50010 : 10.20.54.186:50010 :
7 /apps/hbase/data/WALs/yhg-hadoop-54188.xxx.com.cn,16020,1645421741628/yhg-hadoop-54188.xxx.com.cn%2C16020%2C1645421741628..meta.1645421767092.meta: blk_1074217464_487302 (replicas: l: 2 d: 0 c: 0 e: 0) 10.20.54.188:50010 : 10.20.54.186:50010 :
...
27363 /ranger/audit/hdfs/20201018/hdfs_ranger_audit_yhg-hadoop-54185.xxx.com.cn.log: blk_1074092260_362169 (replicas: l: 2 d: 0 c: 0 e: 0) 10.20.54.186:50010 : 10.20.54.187:50010 :
27364 Mis-replicated blocks that have been postponed:
27365 Metasave: Blocks being replicated: 1
27366 blk_1074194618_464433 StartTime: 09:53:25 NumReplicaInProgress: 1
27367 Metasave: Blocks 0 waiting deletion from 0 datanodes.
27368 Corrupt Blocks:
27369 Metasave: Number of datanodes: 3
27370 10.20.54.186:50010 IN 563438292480(524.74 GB) 243224936448(226.52 GB) 43.17% 319746468176(297.79 GB) 0(0 B) 0(0 B) 100.00% 0(0 B) Mon Feb 21 14:04:57 CST 2022
27371 10.20.54.188:50010 IN 563438292480(524.74 GB) 243148734464(226.45 GB) 43.15% 319822670160(297.86 GB) 0(0 B) 0(0 B) 100.00% 0(0 B) Mon Feb 21 14:04:57 CST 2022
27372 10.20.54.187:50010 IN 563438292480(524.74 GB) 32843665966(30.59 GB) 5.83% 530336495115(493.91 GB) 0(0 B) 0(0 B) 100.00% 0(0 B) Mon Feb 21 14:04:55 CST 2022
啟動過程中遇到的問題
問題1
2020-10-16 01:17:27,500 INFO impl.MetricsSystemImpl (MetricsSystemImpl.java:shutdown(606)) -
NameNode metrics system shutdown complete. 2020-10-16 01:17:27,501 ERROR namenode.NameNode
(NameNode.java:main(1783)) - Failed to start namenode. java.io.FileNotFoundException:
/export/hadoop/hdfs/namenode/current/VERSION (Permission denied) at
java.io.RandomAccessFile.open0(Native Method) at
java.io.RandomAccessFile.open(RandomAccessFile.java:316)
datanode啟動失敗 Changing permission for /export4/hadoop/hdfs/data/ from 755 to 750
解決
chown -R hdfs:hadoop /export[1-12]/hadoop/
問題2
Blocks with no live replicas!=0 這意味著蝙叛,有些塊只有一個副本俺祠,就在當(dāng)前節(jié)點上,如果數(shù)據(jù)節(jié)點被“刪除”借帘,則帶有這些塊的文件將被損壞蜘渣。
- 解決
優(yōu)雅的方法是通過一個使用來自-dfsadmin命令“metasave”。
rm /tmp/single_replica
hdfs dfsadmin -metasave metasave-report.txt
cat /path/to/logs/hadoop/hdfs/metasave-report.txt | grep "l: 1" | cut -d':' -f1 >> /tmp/single_replica
for hdfsfile in `cat /tmp/single_replica`; do hadoop fs -setrep 3 $hdfsfile; done
設(shè)置副本數(shù)為3肺然,依靠集群進(jìn)行復(fù)制蔫缸。
image.png
問題3
報錯 invalidate block
- 情況1、在DataNode的塊匯報以及增量塊匯報操作時狰挡,NameNode會將匯報的數(shù)據(jù)塊副本信息與當(dāng)前NameNode內(nèi)存中的數(shù)據(jù)塊信息對比捂龄,然后計算出損壞的數(shù)據(jù)塊副本释涛,NameNode會調(diào)用BlockManager.markBlockAsCorrupt()方法處理損壞的副本
- 情況2、客戶端讀文件以及DataNode的數(shù)據(jù)塊掃描器都可能發(fā)現(xiàn)損壞的數(shù)據(jù)塊副本倦沧,客戶端會通過ClientProtocol.reportBadBlocks()方法向NameNode匯報損壞的數(shù)據(jù)塊副本唇撬,DataNode會通過DatanodeProtocol.reportBadBlocks()方法向NameNode匯報損壞的數(shù)據(jù)塊副本。
markBlockAsCorrupt()方法會將損壞的副本加入corruptReplicas隊列中展融,然后判斷該副本對應(yīng)的數(shù)據(jù)塊是否有足夠的副本數(shù)量窖认,如果數(shù)據(jù)塊已經(jīng)有足夠的備份數(shù)量,則將調(diào)用invalidateBlock()方法直接將損壞的副本加入invalidateBlocks隊列中進(jìn)行刪除操作告希。如果副本系數(shù)不足扑浸,則更新neededReplications隊列,復(fù)制該數(shù)據(jù)塊
使用invalidateBlock()方法刪除副本的操作主要包括兩個部分:
①調(diào)用addToInvalidates()方法將數(shù)據(jù)塊加入invalidateBlocks隊列中燕偶,之后BlockManager會將這個副本的刪除指令通過心跳響應(yīng)發(fā)送給Datanode喝噪。
②調(diào)用removeStoredBlock()從BlockManager.blocksMap中移除這個DataNode上的副本信息,同時更新excessReplicateMap指么、corruptReplicas以及neededReplications隊列酝惧。
當(dāng)觸發(fā)NAMENODE的雙活切換(active-namenode給zk的心跳超時會發(fā)生)
Datanode增量匯報該block-datanode映射給 namenode(切換后的active namenode)的時候,edit log還沒從JournalNode同步過來伯诬,這時在namenode中已經(jīng)有了block-datanode映射(從剛才datanode的report中來)晚唇,但是還沒有block-file映射(從edits文件里面來),導(dǎo)致namenode認(rèn)為這個塊不屬于任何文件盗似,定義為該塊為invalidate block哩陕。
這個在后臺日志可以查到(后臺standby沒有完全變成activenamenode之前,會出現(xiàn)包含 invalidate block 的后臺日志赫舒。)
edits文件(包含block-file映射): 對于HDFS文件來說悍及,包含的信息有修改時間、訪問時間号阿、塊大小和組成一個文件塊信息等并鸵;而對于目錄來說,包含的信息主要有修改時間扔涧、訪問控制權(quán)限等信息
- 解決
重新上報block信息
hdfs dfsadmin -triggerBlockReport datanode_ip:port
注意
1、如果元數(shù)據(jù)完全丟失届谈,datanode沒有存儲數(shù)據(jù)和塊的關(guān)聯(lián)信息枯夜,所以集群數(shù)據(jù)無法恢復(fù)
2、經(jīng)此一役艰山,一定要做好元數(shù)據(jù)備份湖雹,所以定期及時的備份fsimage、edits和seen_txid文件非常重要(建議直接備份current整個目錄)曙搬!即使存在HA的架構(gòu)建議也備份下摔吏,多一份備份多一分安全。