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