disable table失敗,運(yùn)維人員該如何處理?
相信每一個(gè)維護(hù)hbase集群的運(yùn)維人員一定碰到過(guò)disable失敗,陷入無(wú)窮的"Region has been PENDING_CLOSE for too long..."狀態(tài),此時(shí)沒(méi)有什么好的辦法處理。經(jīng)常需要重啟集群。
這個(gè)問(wèn)題產(chǎn)生的原因非常討厭,經(jīng)過(guò)一段時(shí)間的分析和驗(yàn)證,得到了根本原因。要理解它,必須從disable的原理說(shuō)起:
- disable線程是一個(gè)DisableTableHandler類,我們看它的handleDisableTable()方法,在while循環(huán)中先獲取table的regions列表,然后調(diào)用BulkDisabler的bulkAssign()方法,等待bulkAssign()返回為true時(shí)則結(jié)束
- 在bulkAssign()方法中啟動(dòng)線程池,然后等待線程池超時(shí),超時(shí)時(shí)間由hbase.bulk.assignment.waiton.empty.rit控制
- 在每個(gè)線程中,先從regions collection中得到regions列表,然后通知rs來(lái)處理該region,并且把該region放入RIT列表中,表示該region正在進(jìn)行處理
- rs處理完region以后,將該region狀態(tài)在zk上置為closing,此時(shí)master得到通知
- master將這個(gè)region從RIT列表中刪除,并從regions列表中刪除。
注意以上最后一步,當(dāng)master把它從RIT中刪除以后,還有短暫的時(shí)間這個(gè)region還在regions列表中,此時(shí)另一個(gè)線程拿到了這個(gè)region,并且此時(shí)這個(gè)region不處于RIT狀態(tài)保護(hù),于是另一個(gè)線程開始重復(fù)以上過(guò)程,而前一個(gè)線程己經(jīng)把它從collection中刪除了,于是后一個(gè)線程再也無(wú)法完成closing事件。直到RIT超時(shí)(默認(rèn)30秒)。
于是有兩個(gè)修改辦法:
1、縮短hbase.bulk.assignment.waiton.empty.rit這個(gè)時(shí)間(默認(rèn)10分鐘,it's too long...),讓它重新進(jìn)行一輪disable,此時(shí)會(huì)先把RIT的region都處理掉再繼續(xù),這樣多幾次嘗試總會(huì)成功的。
2、修改代碼:(https://issues.apache.org/jira/secure/attachment/12487669/HBASE-4064_branch90V2.patch)
- Index: src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
- ===================================================================
- --- src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (revision 1150529)
- +++ src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (working copy)
- @@ -767,14 +767,15 @@
- * @param regionInfo
- */
- public void regionOffline(final HRegionInfo regionInfo) {
- + // remove the region plan as well just in case.
- + clearRegionPlan(regionInfo);
- + setOffline(regionInfo);
- +
- synchronized(this.regionsInTransition) {
- if (this.regionsInTransition.remove(regionInfo.getEncodedName()) != null) {
- this.regionsInTransition.notifyAll();
- }
- }
- - // remove the region plan as well just in case.
- - clearRegionPlan(regionInfo);
- - setOffline(regionInfo);
- }
即在以上步驟5時(shí),先從regions列表中刪除,再清除它的RIT狀態(tài)。
方法2己經(jīng)測(cè)試成功,方法1更簡(jiǎn)單,各位被這個(gè)問(wèn)題困擾的同學(xué)可以一試。
原文鏈接:koven2049.iteye.com