您好,登錄后才能下訂單哦!
一、概要
公司近期Storm清洗程序那邊反應(yīng)HDFS會(huì)出現(xiàn)偶發(fā)性的異常導(dǎo)致數(shù)據(jù)寫不進(jìn)HDFS,另外一些Spark作業(yè)在大規(guī)模往HDFS灌數(shù)據(jù)時(shí)客戶端會(huì)出現(xiàn)各種“all datanode bad..”以及服務(wù)端出現(xiàn)各種timeout,值得注意的是出現(xiàn)這樣的問(wèn)題是各個(gè)datanode節(jié)點(diǎn)的負(fù)載并不高!
二、故障分析
首先,當(dāng)我們?cè)贖DFS客戶端看到各種timeOut...什么waiting for reading等信息的時(shí)候,我們第一反應(yīng)是為什么在往HDFS寫數(shù)據(jù)時(shí)組成pipeline的各個(gè)datanode接收不到上游datanode的packet?這時(shí)候往往有人會(huì)說(shuō)增加什么與客戶端的超時(shí)時(shí)間,這個(gè)是肯定不行的(因?yàn)楦鱾€(gè)節(jié)點(diǎn)的負(fù)載非常低)。另外,如果出現(xiàn)“All datanode bad..”這種錯(cuò)誤,我們往往會(huì)最先蹦出2種想法,第一:所有datanode都無(wú)法提供服務(wù)了,第二:dfsClient與hdfs服務(wù)端的DataXServer線程連接但是長(zhǎng)時(shí)間沒(méi)有packet傳輸而導(dǎo)致hdfs服務(wù)端啟動(dòng)保護(hù)機(jī)制自動(dòng)斷開,最終導(dǎo)致。
對(duì)于現(xiàn)在“All datanode bad..”這種問(wèn)題,我基本可以排除第二種情況。再往下看,在平臺(tái)監(jiān)控系統(tǒng)中觀察datanode的Thread Dump信息以及心跳信息,發(fā)現(xiàn)問(wèn)題了:
重現(xiàn)異常情況,觀察所有datanode的Thread Dump和心跳情況:
這個(gè)非常恐怖,心跳達(dá)到30s?。?/p>
更進(jìn)一步分析,直接重現(xiàn)谷中,用jstack -l 命令看datanode具體的Thread Dump信息發(fā)現(xiàn)系統(tǒng)高密度調(diào)用FsDataSetImp中createTemporary和checkDirs方法:
由于上面頻發(fā)調(diào)用在粗粒度對(duì)象鎖FsDatasetImpl作用下的方法,導(dǎo)致發(fā)送心跳以及DataXceiver線程被blocked掉(因?yàn)樗麄兺瑯釉诖至6葘?duì)象鎖FsDatasetImpl作用下),看Thread Dump信息,DataNode處理請(qǐng)求的DataXceiver線程被blocked:
發(fā)送心跳線程被blocked掉:
對(duì)于發(fā)送心跳的線程被blocked掉,從源碼的看來(lái)主要是由于datanode向namenode發(fā)送心跳需要獲得所在節(jié)點(diǎn)的資源相關(guān)情況,心跳通過(guò)getDfUsed,getCapacity,getAvailable,getBlockPoolUsed等方法獲得(看FsDatasetImpl代碼):
而這幾個(gè)方法又是在FsDatasetImpl對(duì)象鎖的作用范圍下,因此心跳線程被blocked掉,具體看下getDfsUsed源碼:
通過(guò)上面一輪的分析,基本可以分析故障原因:大規(guī)模往hdfs同時(shí)寫多批文件,Datanode Thread Dump大量DataXceiver和發(fā)送心跳線程被Blocked掉,出現(xiàn)心跳異常有時(shí)候達(dá)到幾十秒左右,大量DataXceiver線程被blocked掉無(wú)法向各個(gè)dfsClient的dataStreamer(向datanode發(fā)送packet)和ResponseProcessor(接收pipeline中datanode的ack)線程提供服務(wù)和datanode的BlockReceiver線程無(wú)法正常工作,最終導(dǎo)致客戶端出現(xiàn)timeOut,或者dfsClient往hdfs寫packet時(shí)整個(gè)PipeLine中的datanode無(wú)法響應(yīng)客戶端請(qǐng)求,進(jìn)而系統(tǒng)內(nèi)部啟動(dòng)pipeline容錯(cuò),但是各個(gè)datanode都由于DataXceiver大量被Blocked掉無(wú)法提供服務(wù),最后導(dǎo)致客戶端報(bào)出“All dataNode are bad....”和服務(wù)端的timoeut。
換句話來(lái)說(shuō)這個(gè)是HDFS中的一個(gè)大BUG。
這個(gè)是hadoop2.6中的bug,代碼中采用了非常大粒度的對(duì)象鎖(FsDatasetImpl),在大規(guī)模寫操作時(shí)導(dǎo)致鎖異常。這個(gè)bug出現(xiàn)在2.5和2.6這2個(gè)版本中(我們新集群用的是2.6),目前這個(gè)bug已經(jīng)在2.6.1和2.7.0這2個(gè)版本中修復(fù)。官方具體給出的Patch信息:
https://issues.apache.org/jira/browse/HDFS-7489
https://issues.apache.org/jira/browse/HDFS-7999
其實(shí)具體的修復(fù)方案就是將這個(gè)大粒度的對(duì)象鎖分解為多個(gè)小粒度的鎖,并且將datande向namenode發(fā)送心跳線程從相關(guān)聯(lián)的鎖中剝離。
為了進(jìn)一步確認(rèn),這是hadoop2.6中一個(gè)bug,我通過(guò)將測(cè)試集群升級(jí)到2.7.1(bug修復(fù)版本),對(duì)比2.7.1bug修復(fù)版本在大規(guī)模寫多批文件時(shí)的datanode心跳線程以及DataXceiver線程的blocked以及心跳間隔情況。下面是hadoop2.7.1表現(xiàn)情況:
通過(guò)大規(guī)模往hdfs寫多批文件,測(cè)試集群升級(jí)到hadoop2.7.1后,客戶端沒(méi)有報(bào)timeout和“All datanode bad...”異常,服務(wù)端也沒(méi)有報(bào)timeOut異常。另外,通過(guò)和上文hadoop2.6.1中圖表展示對(duì)比,發(fā)現(xiàn)這個(gè)bug在2.7.1得到了解決。
三、故障處理
這個(gè)故障對(duì)我們現(xiàn)有業(yè)務(wù)的影響大概有:
a、影響某個(gè)時(shí)間點(diǎn)通過(guò)storm寫入hdfs的數(shù)據(jù)
b、作業(yè)提交時(shí)間點(diǎn)剛剛好遇到這個(gè)hdfs異常觸發(fā)點(diǎn)時(shí),會(huì)導(dǎo)致作業(yè)附屬文件無(wú)法上傳至hdfs最終導(dǎo)致作業(yè)提交失敗.
c、如果hdfs這個(gè)異常點(diǎn)中時(shí)間拉長(zhǎng),可能會(huì)導(dǎo)致MR作業(yè)的的容錯(cuò)觸發(fā)次數(shù)超過(guò)3次,最終導(dǎo)致作業(yè)失敗。
具體處理方案:在不停機(jī)的情況下采用平滑升級(jí)至hadoop2.7.1版本
具體的升級(jí)步驟按照http://hadoop.apache.org/docs/r2.6.0/hadoop-project-dist/hadoop-hdfs/HdfsRollingUpgrade.html來(lái)就ok。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。